Get the name of the caller script in bash script

Let's assume I have 3 shell scripts:

script_1.sh

#!/bin/bash
./script_3.sh

script_2.sh

#!/bin/bash
./script_3.sh

the problem is that in script_3.sh I want to know the name of the caller script.

so that I can respond differently to each caller I support

please don't assume I'm asking about $0 cause $0 will echo script_3 every time no matter who is the caller

here is an example input with expected output

  • ./script_1.sh should echo script_1

  • ./script_2.sh should echo script_2

  • ./script_3.sh should echo user_name or root or anything to distinguish between the 3 cases?

Is that possible? and if possible, how can it be done?

this is going to be added to a rm modified script... so when I call rm it do something and when git or any other CLI tool use rm it is not affected by the modification


Based on @user3100381's answer, here's a much simpler command to get the same thing which I believe should be fairly portable:

PARENT_COMMAND=$(ps -o comm= $PPID)

Replace comm= with args= to get the full command line (command + arguments). The = alone is used to suppress the headers.

See: http://pubs.opengroup.org/onlinepubs/009604499/utilities/ps.html


In case you are sourceing 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


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

explanations :

  • $PPID is defined by the shell, it's the pid of the parent processes
  • in /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 PID

Check man proc


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 arguments

So a slight simplification.

sed 's/\x0/ /g' "/proc/$PPID/cmdline"