我写了一个简单的shell脚本如下:
#!/bin/bash
sleep 90
运行此 shell 后,我pstree
在单独的 shell 中运行以查看进程树结构。
这是我所看到的
-gnome-terminal-+-bash---sleepy.sh---sleep
我期待这会是这样
-gnome-terminal-+-bash---bash---sleep
为什么 shell 脚本被 pstree 表示为进程?该ps
命令正确地将正在执行的命令显示为
10150 8771 0 08:13 pts/1 00:00:00 /bin/bash ./sleepy.sh
这里的进程是 bash,sleepy.sh 是它的参数(这对我来说很有意义)。在我看来,进程必须是可执行可链接格式二进制文件(ELF)。 Bash 是一个 ELF 可执行文件,但 shell 脚本不是,因此我认为pstree
不应该这样显示它?
答案1
pstree
从中检索进程名称/proc/<pid>/stat
。这是给予内核的任何内容通过 execve(2)
的第一个参数;看proc(5)
和当我在 shell 中执行文件时到底会发生什么?了解详情。从后者你会看到内核能直接运行 shell 脚本(以及许多其他“二进制文件”——参见Mono 有何神奇之处?),但在某些情况下 shell 也会介入。
因此,如果你运行
./sleepy.sh
在脚本开头有一个 shebang 行,您将看到sleepy.sh
inpstree
的输出,因为这是 shell 要求内核运行的内容。如果你运行
sh ./sleepy.sh
你会在的输出sh
中看到。pstree
ps -f
或ps u
(和pstree -a
)读取/proc/<pid>/cmdline
来检索命令行,这是不同的——它是argv
传递给系统调用的参数execve
。当运行带有 shebang 的 shell 脚本时,这会更改为包含 shebang,这无疑是为什么你的情况ps
显示
/bin/bash ./sleepy.sh
(看程序如何运行有关于此的更多信息)。