在 bash 脚本中获取调用者脚本的名称
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20572934/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get the name of the caller script in bash script
提问by a14m
Let's assume I have 3 shell scripts:
假设我有 3 个 shell 脚本:
script_1.sh
脚本_1.sh
#!/bin/bash
./script_3.sh
script_2.sh
脚本_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.
问题是script_3.sh
我想知道调用者脚本的名称。
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
请不要以为我问$0
原因$0
会响应script_3
每一次不管是谁来电
here is an example input with expected output
这是一个具有预期输出的示例输入
./script_1.sh
should echoscript_1
./script_2.sh
should echoscript_2
./script_3.sh
should echouser_name or root or anything to distinguish between the 3 cases
?
./script_1.sh
应该回声script_1
./script_2.sh
应该回声script_2
./script_3.sh
应该回声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
这将被添加到rm
修改后的脚本中......所以当我调用rm
它时做一些事情并且当git
或任何其他 CLI 工具使用rm
它时它不受修改的影响
回答by Thomas Guyot-Sionnest
Based on @user3100381's answer, here's a much simpler command to get the same thing which I believe should be fairly portable:
基于@user3100381 的回答,这里有一个更简单的命令来获得我认为应该相当便携的东西:
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.
更换comm=
用args=
得到完整的命令行(命令+参数)。该=
单独用来抑制头。
See: http://pubs.opengroup.org/onlinepubs/009604499/utilities/ps.html
请参阅:http: //pubs.opengroup.org/onlinepubs/009604499/utilities/ps.html
回答by user3100381
The $PPID variable holds the parent process ID. So you could parse the output from ps to get the command.
$PPID 变量保存父进程 ID。所以你可以解析 ps 的输出来获取命令。
#!/bin/bash
PARENT_COMMAND=$(ps $PPID | tail -n 1 | awk "{print $5}")
回答by Kashyap
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.
如果您是source
ing 而不是调用/执行脚本,则没有新进程分叉,因此解决方案ps
将无法可靠地工作。
Use bash built-in caller
in that case.
caller
在这种情况下使用内置的 bash 。
$ 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
$
回答by Gilles Quenot
Based on @J.L.answer, with more in depth explanations (the only one command that works for me (linux)) :
基于@JLanswer,有更深入的解释(唯一对我有用的命令(linux)):
cat /proc/$PPID/comm
gives you the name of the command of the parent pid
为您提供父pid命令的名称
If you prefer the command with all options, then :
如果您更喜欢带有所有选项的命令,那么:
cat /proc/$PPID/cmdline
explanations :
解释:
$PPID
is defined by the shell, it's the pidof the parent processes- in
/proc/
, you have some dirs with the pidof each process (linux). Then, if youcat /proc/$PPID/comm
, you echo the command name of the PID
Check man proc
检查man proc
回答by J.L.
If you have /proc
:
如果你有/proc
:
$(cat /proc/$PPID/comm)
回答by Reinstate Monica Please
Couple of useful files things kept in /proc/$PPID here
一些有用的文件保存在 /proc/$PPID 中
/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
/proc/*some_process_id*/exe
*some_process_id* 下最后执行的命令的符号链接/proc/*some_process_id*/cmdline
在 *some_process_id* 下包含最后执行的命令和空字节分隔参数的文件
So a slight simplification.
所以稍微简化一下。
sed 's/\x0/ /g' "/proc/$PPID/cmdline"
回答by Six
You can simply use the command below to avoid calling cut/awk/sed:
您可以简单地使用以下命令来避免调用 cut/awk/sed:
ps --no-headers -o command $PPID
If you only want the the parent and none of the subsequent processes, you can use:
如果您只需要父进程而不需要后续进程,则可以使用:
ps --no-headers -o command $PPID | cut -d' ' -f1
回答by Snehasish Sarkar
Declare this:
声明如下:
PARENT_NAME=`ps -ocomm --no-header $PPID`
Thus you'll get a nice variable $PARENT_NAME that holds the parent's name.
因此你会得到一个很好的变量 $PARENT_NAME ,它保存了父母的名字。
回答by Donovan
You could pass in a variable to script_3.sh to determine how to respond...
您可以将变量传递给 script_3.sh 以确定如何响应...
script_1.sh
脚本_1.sh
#!/bin/bash
./script_3.sh script1
script_2.sh
脚本_2.sh
#!/bin/bash
./script_3.sh script2
script_3.sh
脚本_3.sh
#!/bin/bash
if [ == 'script1' ] ; then
echo "we were called from script1!"
elsif [ == 'script2' ] ; then
echo "we were called from script2!"
fi