开发者

Will () construct always start a subshell?

开发者 https://www.devze.com 2023-03-04 08:49 出处:网络
Curr开发者_运维百科ent shell is $ echo $$ 23173 Note the parent of ps is current shell $ ( ps -o pid,ppid,cmd )

Curr开发者_运维百科ent shell is

$ echo $$
23173

Note the parent of ps is current shell

$ ( ps -o pid,ppid,cmd )
  PID  PPID CMD
 8952 23173 ps -o pid,ppid,cmd
23173 23169 bash

But here , the parent of ps is the subshell (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

Is bash doing optimizations ? How come an extra echo made the the difference and spawned a subshell in 3rd case ?


Yes, what you're seeing is an optimization. Technically, the (…) construct always starts a subshell, by definition. Most of the time, the subshell runs in a separate subprocess. This ensures that everything done in the subshell stays in the subshell. If bash can guarantee this isolation property, it's free to use any implementation technique it likes.

In the fragment ( ps -o pid,ppid,cmd ), it's obvious that nothing can influence the parent shell, so there's an optimization in bash that makes it not fork a separate process for the subshell. The fragment ( echo hello ; ps -o pid,ppid,cmd ) is too complex for the optimizer to recognize that no subshell is needed.

If you experiment with ksh, you'll notice that its optimizer is more aggressive. For example, it doesn't fork a subprocess for ( echo hello ; ps -o pid,ppid,cmd ) either.


A subshell consisting of a single simple command instead of a list or pipeline of more than one command could be implemented by simply "execing" the command, i.e. replacing the subshell with the process for the command called. If the subshell is more complex then a simple exec is not possible, the subshell must stay around to manage the command sequence.

From your diagnostics it's impossible to tell the difference between a bash optimization where a subshell consisting of a simple command is optimized to a "direct" fork and exec of the called command or a fork of a subshell followed by an exec of the command called. This isn't surprising as the difference is (almost?) entirely academic.

0

精彩评论

暂无评论...
验证码 换一张
取 消