Why does command grouping with curly brackets caus

2019-07-29 07:09发布

Consider the following command

$ bash -c "  sleep 10000  | sed 's/ Something//g '"

The process tree due to that command looks like this;

   \-+= 69771 hbaba -bash
     \-+= 39225 hbaba bash -c   sleep 10000  | sed 's/ Something//g '
       |--- 39226 hbaba sleep 10000
       \--- 39227 hbaba sed s/ Something//g

Adding command grouping with curly brackets changes the process tree significantly.

$ bash -c " { sleep 10000; } | sed 's/ Something//g '"

The bash process is spawned twice

 \-+= 69771 hbaba -bash
         \-+= 39323 hbaba bash -c  { sleep 10000; } | sed 's/ Something//g '
           |-+- 39324 hbaba bash -c  { sleep 10000; } | sed 's/ Something//g '
           | \--- 39326 hbaba sleep 10000
           \--- 39325 hbaba sed s/ Something//g

What is the reason of this duplication ?


The documentation section about curly braces mentions this:

Placing a list of commands between curly braces causes the list to be executed in the current shell context. No subshell is created.

What I see does not look like current shell context to me. A new subshell should not be created. We are not using parenthesis.


I understand that bash spawns each process in a pipe in its own subshell

From the doc:

Each command in a pipeline is executed in its own subshell

I am not asking why the sleep and sed are two different processes. I am asking about the two bashes: 39323 and 39324


I am using this bash version

$ bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)

Update

I have found this related question in Unix&Linux . I think that answers it. There is still some unclarified aspects though. In that question the curly braces were nested. In addition, this answer there shows that the extra subshell creation happens with pipes but not with semicolon separated commands.

Indeed this command does not create the extra subshell.

bash -c " { sleep 10000; } ; sed 's/ Something//g '"

Here is the process tree. I guess the parallel execution of piped commands also plays a role in this extra subshell creation.

bash,100648
  └─bash,104674 -c  { sleep 10000; } ; sed 's/ Something//g '
      └─sleep,104675 10000

0条回答
登录 后发表回答