首页 > 解决方案 > 为什么在分组命令中执行简单命令不会fork子shell进程,而复合命令会这样做

问题描述

我知道分组命令(command-list)会创建一个子shell 环境,并且每个列出的命令都在该子shell中执行。但是如果我在分组命令中执行一个简单ps的命令,(使用命令输出进程),那么没有子shell进程输出。但是,如果我尝试在分组命令中执行命令列表(复合命令),则会输出一个子shell 进程。为什么会产生这样的结果?

我测试了很多其他命令(复合命令和简单命令),但结果都是一样的。我想即使我在分组命令中执行一个简单的命令,bash也应该分叉一个子shell进程,否则它无法执行命令。但是为什么我看不到呢?

标签: linuxbashshellsubshell

解决方案


Bash 优化了执行。它检测到只有一个命令在( )组内并调用fork+exec而不是fork+ fork+ exec。这就是为什么您bash在进程列表中看到的进程更少的原因。( sleep 5 )当使用需要更多时间来消除时序的命令时,更容易检测到。此外,您可能想在 unix.stackexchange 上阅读此线程。

我认为优化是execute_cmd.cexecute_in_subshell()函数内部的某个地方完成的(我添加的箭头>):

 /* If this is a simple command, tell execute_disk_command that it
     might be able to get away without forking and simply exec.
>>>> This means things like ( sleep 10 ) will only cause one fork
     If we're timing the command or inverting its return value, however,
     we cannot do this optimization. */

execute_disk_command()函数中我们还可以阅读:

/* If we can get away without forking and there are no pipes to deal with,
   don't bother to fork, just directly exec the command. */

推荐阅读