shell 在bash脚本中获取调用者脚本的名称

ipakzgxi  于 2023-01-21  发布在  Shell
关注(0)|答案(9)|浏览(221)

假设我有3个shell脚本:

脚本_1.sh

#!/bin/bash
./script_3.sh

脚本_2.sh

#!/bin/bash
./script_3.sh

问题是在script_3.sh中我想知道调用者脚本的名称。

以便我可以对我支持的每个来电者做出不同的响应

  • 请不要以为我问的是$0,因为$0每次都会回应script_3,无论调用者是谁 *

以下是具有预期输出输入示例

  • ./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

这可能吗?如果可能,怎么做?

这将添加到rm修改的脚本中...因此,当我调用rm时,它会执行一些操作,而当git或任何其他CLI工具使用rm时,它不受修改的影响

omqzjyyz

omqzjyyz1#

根据@user3100381的回答,这里有一个简单得多的命令来获得同样的东西,我相信它应该是相当可移植的:

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

comm=替换为args=以获得完整的命令行(命令+参数)。=单独用于隐藏标头。
参见:http://pubs.opengroup.org/onlinepubs/009604499/utilities/ps.html

q5lcpyga

q5lcpyga2#

如果您使用source而不是调用/执行脚本,则没有新的进程分支,因此ps的解决方案将无法可靠地工作。
在这种情况下,使用bash内置的caller

$ cat h.sh 
#! /bin/bash 
function warn_me() { 
    echo "$@" 
    caller 
}
$ 
$ cat g.sh 
#!/bin/bash 
source h.sh 
warn_me "Error: You did not do something" 
$
$ . g.sh 
Error: You did not do something
g.sh
$

Source

7bsow1i6

7bsow1i63#

$PPID变量保存父进程ID,因此您可以解析ps的输出以获取命令。

#!/bin/bash
PARENT_COMMAND=$(ps $PPID | tail -n 1 | awk "{print \$5}")
nkoocmlb

nkoocmlb4#

基于@J.L.的回答,并提供了更深入的解释,适用于linux

cat /proc/$PPID/comm

提供父pid的命令名称
如果希望命令包含所有选项,则:

cat /proc/$PPID/cmdline

解释:

  • $PPID由shell定义,它是父进程的pid
  • /proc/中,每个进程(linux)的pid都有一些目录。然后,如果使用cat /proc/$PPID/comm,则回显PID的命令名

检查man proc

q1qsirdb

q1qsirdb5#

一些有用的文件保存在/proc/$PPID中

  • /proc/*some_process_id*/exesome_process_id 下最后执行的命令的符号链接
  • /proc/*some_process_id*/cmdline包含 some_process_id 下最后执行的命令和空字节分隔参数的文件

稍微简化一下。

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

nr9pn0ug6#

如果您有/proc

$(cat /proc/$PPID/comm)
szqfcxe2

szqfcxe27#

兹宣告:

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

因此,您将获得一个保存父对象名称的漂亮变量$PARENT_NAME。

6jjcrrmo

6jjcrrmo8#

您可以简单地使用下面的命令来避免调用cut/awk/sed:

ps --no-headers -o command $PPID

如果只需要父进程而不需要任何后续进程,则可以用途:

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

jobtbby39#

您可以向script_3.sh传递一个变量,以确定如何响应...

    • 脚本_1.sh**
#!/bin/bash
./script_3.sh script1
    • 脚本_2.sh**
#!/bin/bash
./script_3.sh script2
    • 脚本_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

相关问题