Let\'s assume I have 3 shell scripts:
script_1.sh
#!/bin/bash
./script_3.sh
script_2.sh
Couple of useful files things kept in /proc/$PPID here
/proc/*some_process_id*/exe
A symlink to the last executed command under *some_process_id*/proc/*some_process_id*/cmdline
A file containing the last executed command under *some_process_id* and null-byte separated argumentsSo a slight simplification.
sed 's/\x0/ /g' "/proc/$PPID/cmdline"
Declare this:
PARENT_NAME=`ps -ocomm --no-header $PPID`
Thus you'll get a nice variable $PARENT_NAME that holds the parent's name.
You could pass in a variable to script_3.sh to determine how to respond...
script_1.sh
#!/bin/bash
./script_3.sh script1
script_2.sh
#!/bin/bash
./script_3.sh script2
script_3.sh
#!/bin/bash
if [ $1 == 'script1' ] ; then
echo "we were called from script1!"
elsif [ $1 == 'script2' ] ; then
echo "we were called from script2!"
fi
The $PPID variable holds the parent process ID. So you could parse the output from ps to get the command.
#!/bin/bash
PARENT_COMMAND=$(ps $PPID | tail -n 1 | awk "{print \$5}")
Based on @J.L.answer, with more in depth explanations (the only one command that works for me (linux)) :
cat /proc/$PPID/comm
gives you the name of the command of the parent pid
If you prefer the command with all options, then :
cat /proc/$PPID/cmdline
$PPID
is defined by the shell, it's the pid of the parent processes/proc/
, you have some dirs with the pid of each process (linux). Then, if you cat /proc/$PPID/comm
, you echo the command name of the PIDIn case you are source
ing instead of calling/executing the script there is no new process forked and thus the solutions with ps
won't work reliably.
Use bash built-in caller
in that case.
$ cat h.sh
#! /bin/bash
function warn_me() {
echo "$@"
caller
}
$ cat g.sh
#!/bin/bash
source h.sh
warn_me "Error: You didn't do something"
$ . g.sh
Error: You didn't do something 3
g.sh
$
Source