Will()构造总是会启动子shell吗?

Ank*_*wal 6 linux bash shell

目前的外壳是

$ echo $$
23173
Run Code Online (Sandbox Code Playgroud)

请注意ps的父级是当前shell

$ ( ps -o pid,ppid,cmd )
  PID  PPID CMD
 8952 23173 ps -o pid,ppid,cmd
23173 23169 bash
Run Code Online (Sandbox Code Playgroud)

但是在这里,ps的父是子shell(bash)

$ ( echo hello ; ps -o pid,ppid,cmd )
hello
  PID  PPID CMD
 8953 23173 bash
 8954  8953 ps -o pid,ppid,cmd
23173 23169 bash
Run Code Online (Sandbox Code Playgroud)

bash在做优化吗?为什么一个额外的回声会产生差异并在第三种情况下产生一个子壳?

Gil*_*il' 6

是的,您所看到的是优化.从技术上讲,(…)根据定义,构造始终会启动子shell.大多数情况下,子shell在一个单独的子进程中运行.这可确保子shell中完成的所有操作都保留在子shell中.如果bash可以保证这种隔离属性,它可以自由使用它喜欢的任何实现技术.

在片段( ps -o pid,ppid,cmd ),很明显,没有什么可以影响到父shell,所以有在bash,使得它无法派生一个单独的进程的子shell的优化.该片段( echo hello ; ps -o pid,ppid,cmd )太复杂,优化器无法识别不需要子shell.

如果你试验ksh,你会注意到它的优化器更具侵略性.例如,它不会为( echo hello ; ps -o pid,ppid,cmd )任何一个子进程分叉.