Get the name of the caller script in bash script

BashShell

Bash Problem Overview


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

Bash Solutions


Solution 1 - Bash

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

Solution 2 - Bash

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

Solution 3 - Bash

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}")

Solution 4 - Bash

Based on @J.L.answer, with more in depth explanations (the only one command that works for me ([tag:linux])) :

cat /proc/$PPID/comm

gives you the name of the command of the parent [tag:pid]

If you prefer the command with all options, then :

cat /proc/$PPID/cmdline

explanations :

  • $PPID is defined by the shell, it's the [tag:pid] of the parent processes
  • in /proc/, you have some dirs with the [tag:PID] of each process ([tag:linux]). Then, if you cat /proc/$PPID/comm, you echo the command name of the PID

Check man proc

Solution 5 - Bash

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"

Solution 6 - Bash

If you have /proc:

$(cat /proc/$PPID/comm)

Solution 7 - Bash

You can simply use the command below to avoid calling cut/awk/sed:

ps --no-headers -o command $PPID

If you only want the parent and none of the subsequent processes, you can use:

ps --no-headers -o command $PPID | cut -d' ' -f1

Solution 8 - Bash

Declare this:

PARENT_NAME=`ps -ocomm --no-header $PPID`

Thus you'll get a nice variable $PARENT_NAME that holds the parent's name.

Solution 9 - Bash

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questiona14mView Question on Stackoverflow
Solution 1 - BashThomas Guyot-SionnestView Answer on Stackoverflow
Solution 2 - BashKashyapView Answer on Stackoverflow
Solution 3 - Bashuser3100381View Answer on Stackoverflow
Solution 4 - BashGilles QuenotView Answer on Stackoverflow
Solution 5 - BashReinstate Monica PleaseView Answer on Stackoverflow
Solution 6 - BashJ.L.View Answer on Stackoverflow
Solution 7 - BashSixView Answer on Stackoverflow
Solution 8 - BashSnehasish SarkarView Answer on Stackoverflow
Solution 9 - BashDonovanView Answer on Stackoverflow