$(pgrep -f) 脚本内的行为会根据 shebang 发生变化

$(pgrep -f) 脚本内的行为会根据 shebang 发生变化

当我运行以下脚本时:

#!/bin/bash
$(pgrep -u ubuntu -f ${1} > /dev/null)
echo "CURRENT_STATUS="${?}

和:

./my_script.sh top

top不运行时,它返回:

CURRENT_STATUS=0

这很奇怪,因为我预计会出现1退出状态pgrep。当我从脚本中删除 shebang 时,它会按预期工作。

有人可以帮助我了解这里发生了什么吗?

这是在 Ubuntu 22.4.1 系统上。另请注意,这$(...)不会改变结果。

我注意到这pgrep似乎与自身匹配,这就是为什么无论我输入什么进程名称它都会给出 0 结果。

答案1

使用 hashbang,内核运行命名解释器,向其传递脚本文件名和您给出的参数,即命令行是/bin/bash ./my_script.sh top,并且在进程列表中显示为 eg ps,并类似地pgrep找到它。top毕竟它与关键字匹配。

如果没有 hashbang,内核级系统调用就会失败,Bash 会在内部运行脚本本身,并且参数不会显示在进程列表中。 (shell 以某种方式做到这一点。IIRC 这是 POSIX 的要求,如果可能的话,非可执行文件必须通过 shell 运行。)

使用以下两个测试更容易:

bash$ cat wait.sh
#!/bin/bash
sleep 50

bash$ cat wait2.sh
sleep 50

bash$ ./wait.sh & ./wait2.sh & ps uax |grep wait
ilkkachu  9029  0.0  0.0  15368  3060 pts/21   S    20:01   0:00 /bin/bash ./wait.sh
ilkkachu  9032  0.0  0.0  16964   968 pts/21   S+   20:01   0:00 grep wait

没有 hashbang 的不会出现。

我认为pgrep足够聪明,不会找到自身,而是帮助它找到脚本,您可以使用类似 的模式'[t]op',它匹配top,但不匹配自身。随着./my_script.sh '[t]op',差异消失。

不过那里的命令替换没什么用,直接丢掉就可以了pgrep

相关内容