bash 是否创建一个子进程来运行每个命令

Ars*_*ngh 4 bash

每次我们ps多次运行一个普通命令时,它都有不同的进程 ID (PID)。我想知道这是否意味着我们在终端(bash)中运行的每个命令都会创建一个 bash 子进程来执行该命令。

ilk*_*chu 8

是的,几乎您在命令行上运行的每个命令都在其自己的进程中运行,并且这些进程是启动它们的 shell 的子进程。

这里的例外是 shell 的内置命令。Bash 本身实现了一些标准实用程序,例如printfechotruefalsekill/ ,因此运行这些[实用test程序并不涉及分叉子项。这同样适用于诸如cdread和 之类的东西mapfile,尽管它们会影响 shell 的内部状态,因此它们必须是内置的。

(此外breakcontinue、 和return,奇怪的是它们是内置实用程序,而不是像if和 那样的 shell 关键字while。)

shell 确实没有办法在与自身相同的进程中运行外部程序,同时仍然能够返回。然而,shell 可以用另一个程序替换自身。例如,如果您运行echo $$查看 shell 的 PID,然后运行exec ps​​,您将看到ps使用相同的 PID 运行。当ps退出时,该 shell 不再存在。fork()实际上,每次以正常方式运行程序时都会发生类似的情况,只是 shell在用要运行的程序替换子程序 ( ) 之前复制自身(系统调用) execve()。在子进程中运行的 shell 程序负责为子进程设置任何重定向等。

shell 也可以将其他工具实现为内置工具,例如 Busybox 实现是同一程序文件中较大的标准实用程序集。但据我测试,它在运行它们时仍然分叉一个子进程,可能是因为这是确保实用程序不会不必要地扰乱 shell 状态的简单方法。