Bash subshell/pipelines - which parts are executing in subshells?

前端 未结 2 726
再見小時候
再見小時候 2020-12-10 04:11

In a comment on another post, @JonathanLeffler stated that:

{ ... } | somecommand is run in a sub-shell and doesn\'t affect the parent shell. Demo:

相关标签:
2条回答
  • 2020-12-10 05:02

    Indeed, the braces are executed in a new subshell, but only if piped. The first command is with cat, the second without:

    xxx@yyy:~$ ps; X=PQR; echo $X; { ps; X=ABC; echo $X; } | cat; ps; echo $X
      PID TTY          TIME CMD
     6768 pts/7    00:00:00 bash
    13158 pts/7    00:00:00 ps
    PQR
      PID TTY          TIME CMD
     6768 pts/7    00:00:00 bash
    13159 pts/7    00:00:00 bash
    13160 pts/7    00:00:00 cat
    13161 pts/7    00:00:00 ps
    ABC
      PID TTY          TIME CMD
     6768 pts/7    00:00:00 bash
    13162 pts/7    00:00:00 ps
    PQR
    xxx@yyy:~$ ps; X=PQR; echo $X; { ps; X=ABC; echo $X; }; ps; echo $X
      PID TTY          TIME CMD
     6768 pts/7    00:00:00 bash
    13239 pts/7    00:00:00 ps
    PQR
      PID TTY          TIME CMD
     6768 pts/7    00:00:00 bash
    13240 pts/7    00:00:00 ps
    ABC
      PID TTY          TIME CMD
     6768 pts/7    00:00:00 bash
    13245 pts/7    00:00:00 ps
    ABC
    

    In this case 6768 is the PID of the terminal shell, and 13159 is the PID of the subshell started for the braces.

    It seems that {} are executed in a subshell if (and only if) piped.

    0 讨论(0)
  • 2020-12-10 05:08

    Each side of a pipeline becomes a subshell at least.

    X=PQR; echo $X; { X=ABC; echo $X; } | cat; echo $X
    

    will make a subshell/process of , atleast { X=ABC; echo $X; } and cat.

    "Each command in a pipeline is executed as a separate process (i.e., in a subshell)." , from man bash

    If you instead do this

    X=PQR; echo $X; { X=ABC; echo $X; } ; echo | cat; echo $X
    

    You'll see afterwards that echo $X shows ABC.

    There's other ways that commands are executed in subshells too, e.g. if you background a subcommand: { X=SUB ; sleep 1; } & , that group will run in a subshell, whereas just { X=SUB ; sleep 1; } will not.

    If you want to group commands that always execute in a subshell, use parenthesis, (X=ABC ; echo $X) instead of braces.

    0 讨论(0)
提交回复
热议问题