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
In bash you can get the script file name using $0 . Generally $1 , $2 etc are to access CLI arguments. Similarly $0 is to access the name which triggers the script(script file name). If you invoke the script with path like /path/to/script.sh then $0 also will give the filename with path.
Bash - Caller - Stack Trace (Builtin command) Caller is a builtin command that returns the context (localization) of any active subroutine call (a shell function or a script executed with the . or source builtins.
$_ (dollar underscore) is another special bash parameter and used to reference the absolute file name of the shell or bash script which is being executed as specified in the argument list. This bash parameter is also used to hold the name of mail file while checking emails.
In 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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With