Linux ps/pgrep找不到缺少的运行脚本#/bin/bash
我发现ps或pgrep无法找到没有“#!/bin/bash”的运行脚本 下面是一个sample.sh:Linux ps/pgrep找不到缺少的运行脚本#/bin/bash,linux,shell,Linux,Shell,我发现ps或pgrep无法找到没有“#!/bin/bash”的运行脚本 下面是一个sample.sh: while true do echo $(date) done 启动脚本(ubu
while true
do
echo $(date)
done
启动脚本(ubuntu 18.04,Linux版本4.15.0-101-generic):
打开另一个终端,ps只找到grep命令
$ps -aux |grep sample.sh
16887 0.0 0.0 16184 1008 pts/4 S+ 07:12 0:00 grep --color=auto sample
pgrep什么也找不到
$pgrep sample
$
但是如果我在sample.sh中添加“#!/bin/bash”,现在一切都正常了:
#!/bin/bash <-----add this line
while true
do
echo $(date)
done
#/bin/bash让我们从您的第二个案例开始,即您确实有#/bin/bash
,因为它实际上是最容易首先处理的
用#/bin/bash
当您执行以#开头的脚本时/path/to/explorer
,Linux内核将理解此语法,并将以与在命令行开头显式添加/path/to/explorer
相同的方式为您调用指定的解释器。因此,对于以开头的脚本/bin/bash
,如果您使用ps-ux查看,您将看到命令行/bin/bash./sample.sh
没有#/bin/bash
现在转到另一个#/缺少bin/bash
。这个案子更微妙
既不是已编译的可执行文件,也不是以开头的文件行。下面是一个在没有#的情况下运行sample.sh
的示例/python脚本中的bin/bash
行:
>>> import subprocess
>>> p = subprocess.Popen("./sample.sh")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/subprocess.py", line 394, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1047, in _execute_child
raise child_exception
OSError: [Errno 8] Exec format error
因此,在这种情况下,当您运行脚本时发生的情况是,因为您是从bash shell调用它的,bash通过在尝试“执行”脚本失败后直接运行命令来提供一些容错能力
更详细的情况是:
- bash分叉了一个次外壳
- 在子shell中,它会直接调用Linux内核“exec”您的可执行文件,如果成功,将结束(子shell)进程,并用运行可执行文件的进程替换它
- 但是,exec没有成功,这意味着子shell仍在运行
- 此时,子shell只读取脚本中的命令,并开始直接执行它们
整体效果与#非常相似/bin/bash
case,但由于子shell刚刚通过分叉原始bash进程启动,因此它具有相同的命令行,即justbash
,没有任何命令行参数。如果您在ps-uxf
的输出(流程的树状视图)中查找此子shell,您将看到它与
bash
\_ bash
而在#中/bin/bash
您得到的案例:
bash
\_ /bin/bash ./sample.sh
让我们从您的第二个案例开始,即您确实有#/bin/bash
,因为它实际上是最容易首先处理的
用#/bin/bash
当您执行以#开头的脚本时/path/to/explorer
,Linux内核将理解此语法,并将以与在命令行开头显式添加/path/to/explorer
相同的方式为您调用指定的解释器。因此,对于以开头的脚本/bin/bash
,如果您使用ps-ux查看,您将看到命令行/bin/bash./sample.sh
没有#/bin/bash
现在转到另一个#/缺少bin/bash
。这个案子更微妙
既不是已编译的可执行文件,也不是以开头的文件行。下面是一个在没有#的情况下运行sample.sh
的示例/python脚本中的bin/bash
行:
>>> import subprocess
>>> p = subprocess.Popen("./sample.sh")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/subprocess.py", line 394, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1047, in _execute_child
raise child_exception
OSError: [Errno 8] Exec format error
因此,在这种情况下,当您运行脚本时发生的情况是,因为您是从bash shell调用它的,bash通过在尝试“执行”脚本失败后直接运行命令来提供一些容错能力
更详细的情况是:
- bash分叉了一个次外壳
- 在子shell中,它会直接调用Linux内核“exec”您的可执行文件,如果成功,将结束(子shell)进程,并用运行可执行文件的进程替换它
- 但是,exec没有成功,这意味着子shell仍在运行
- 此时,子shell只读取脚本中的命令,并开始直接执行它们
整体效果与#非常相似/bin/bash
case,但由于子shell刚刚通过分叉原始bash进程启动,因此它具有相同的命令行,即justbash
,没有任何命令行参数。如果您在ps-uxf
的输出(流程的树状视图)中查找此子shell,您将看到它与
bash
\_ bash
而在#中/bin/bash
您得到的案例:
bash
\_ /bin/bash ./sample.sh
我想这取决于您的bash版本,因为我无法通过bash5.0.11获得sample.sh
的PID。但是如果我把printf'boogaloo'>/proc/self/comm
放在sample.sh
的第一行,我可以通过pgrep boogaloo
@camino获得它的PID:当然,一个区别是没有#!第行,脚本将由sh
运行,但这仍然不能为我解释差异。如果通过sh sample.sh
显式启动脚本,与bash sample.sh
相比会发生什么?@user1934428 sh sample.sh,ps aux | grep sample.sh可以工作。我想这取决于您的bash版本,因为我无法通过bash 5.0.11获得sample.sh
的PID。但是如果我把printf'boogaloo'>/proc/self/comm
放在sample.sh
的第一行,我可以通过pgre获得它的PID