我发现ps或pgrep在没有“#!/ bin / bash”的情况下找不到运行的脚本
这里是一个示例。sh:
while true
do
echo $(date)
done
启动脚本(ubuntu 18.04,Linux版本4.15.0-101-通用):
$echo $BASH
/bin/bash
./sample.sh
打开另一个终端,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
$
但是如果我将“#!/ bin / bash”添加到sample.sh,则现在一切正常:
#!/bin/bash <-----add this line
while true
do
echo $(date)
done
我想知道为什么。
让我们从您的第二个案例开始,即您do拥有#!/bin/bash
,因为实际上这是更容易处理的第一个案例。
#!/bin/bash
[当您执行以#!/path/to/interpreter
开头的脚本时,Linux内核将理解此语法,并以与您在命令行开头显式添加/path/to/interpreter
相同的方式为您调用指定的解释器。因此,对于以#!/bin/bash
开头的脚本,如果您使用ps ux
,则将看到命令行/bin/bash ./sample.sh
。
#!/bin/bash
现在转到缺少#!/bin/bash
的另一位置。这种情况更加微妙。
既不是已编译的可执行文件,也不是以#!
行开头的文件Linux内核完全无法执行]。>这是一个尝试从python脚本运行不带sample.sh
行的#!/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
并且为了证明这不仅仅是一个python问题,这是一个完全相同的示例,而是一个C程序的演示。这是C代码:
#include <stdio.h> #include <unistd.h> int main() { execl("./sample.sh", "sample.sh", NULL); /* exec failed if reached */ perror("exec failed:"); return 1; }
这是输出:
,bash通过在尝试“执行”脚本后直接运行命令来提供一定的容错能力失败。exec failed:: Exec format error
因此,运行脚本时发生的情况是因为您正在从bash shell调用它
更详细的是:
bash分叉一个子shell,
直接在子shell内调用Linux内核以“执行”您的可执行文件,并且如果成功
但是,执行成功not
,这意味着子shell仍在运行此时,子shell会读取脚本中的命令并直接开始执行它们。
总体效果与#!/bin/bash
情况非常相似,但是由于子shell只是通过派生原始bash进程而启动的,因此它具有相同的命令行,即只有bash
,没有任何命令行参数。如果您在ps uxf
的输出(进程的树状视图)中寻找此子外壳,您将看到它就像
bash \_ bash
而在
#!/bin/bash
情况下,您得到:bash \_ /bin/bash ./sample.sh