Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux ps/pgrep找不到缺少的运行脚本#/bin/bash_Linux_Shell - Fatal编程技术网

Linux ps/pgrep找不到缺少的运行脚本#/bin/bash

Linux ps/pgrep找不到缺少的运行脚本#/bin/bash,linux,shell,Linux,Shell,我发现ps或pgrep无法找到没有“#!/bin/bash”的运行脚本 下面是一个sample.sh: while true do echo $(date) done 启动脚本(ubu

我发现ps或pgrep无法找到没有“#!/bin/bash”的运行脚本

下面是一个sample.sh:

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进程启动,因此它具有相同的命令行,即just
bash
,没有任何命令行参数。如果您在
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进程启动,因此它具有相同的命令行,即just
bash
,没有任何命令行参数。如果您在
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