当我运行以下脚本时:
#!/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
。