在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 00:31:32  来源:igfitidea点击:

Get the name of the caller script in bash script

bashshell

提问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.shI 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 $0cause $0will echo script_3every time no matter who is the caller

请不要以为我问$0原因$0会响应script_3每一次不管是谁来电

here is an example input with expected output

这是一个具有预期输出的示例输入

  • ./script_1.shshould echo script_1

  • ./script_2.shshould echo script_2

  • ./script_3.shshould echo user_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 rmmodified script... so when I call rmit do something and when gitor any other CLI tool use rmit 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 sourceing instead of calling/executing the script there is no new process forked and thus the solutions with pswon't work reliably.

如果您是sourceing 而不是调用/执行脚本,则没有新进程分叉,因此解决方案ps将无法可靠地工作。

Use bash built-in callerin 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
$

Source

来源

回答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 :

解释:

  • $PPIDis 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 you cat /proc/$PPID/comm, you echo the command name of the PID
  • $PPID由 shell 定义,它是父进程的pid
  • 在 中/proc/,您有一些带有每个进程(linux)的pid的目录。然后,如果你,你回显PID的命令名称cat /proc/$PPID/comm

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*/exeA symlink to the last executed command under *some_process_id*
  • /proc/*some_process_id*/cmdlineA 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