为什么 pstree 显示我的脚本的名称而不是解释它的 shell 的名称?

为什么 pstree 显示我的脚本的名称而不是解释它的 shell 的名称?

我写了一个简单的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.shinpstree的输出,因为这是 shell 要求内核运行的内容。如果你运行

sh ./sleepy.sh

你会在的输出sh中看到。pstree

ps -fps u(和pstree -a)读取/proc/<pid>/cmdline来检索命令行,这是不同的——它是argv传递给系统调用的参数execve。当运行带有 shebang 的 shell 脚本时,这会更改为包含 shebang,这无疑是为什么你的情况ps显示

/bin/bash ./sleepy.sh

(看程序如何运行有关于此的更多信息)。

相关内容