When does command substitution spawn more subshells than the same commands in isolation?

前端 未结 2 1617
挽巷
挽巷 2020-12-01 03:53

Yesterday it was suggested to me that using command substitution in bash causes an unnecessary subshell to be spawned. The advice was specific to this use case:



        
2条回答
  •  情书的邮戳
    2020-12-01 04:40

    In Bash, a subshell always executes in a new process space. You can verify this fairly trivially in Bash 4, which has the $BASHPID and $$ environment variables:

    • $$ Expands to the process ID of the shell. In a () subshell, it expands to the process ID of the current shell, not the subshell.
    • BASHPID Expands to the process id of the current bash process. This differs from $$ under certain circumstances, such as subshells that do not require bash to be re-initialized

    in practice:

    $ type echo
    echo is a shell builtin
    $ echo $$-$BASHPID
    4671-4671
    $ ( echo $$-$BASHPID )
    4671-4929
    $ echo $( echo $$-$BASHPID )
    4671-4930
    $ echo $$-$BASHPID | { read; echo $REPLY:$$-$BASHPID; }
    4671-5086:4671-5087
    $ var=$(echo $$-$BASHPID ); echo $var
    4671-5006
    

    About the only case where the shell can elide an extra subshell is when you pipe to an explicit subshell:

    $ echo $$-$BASHPID | ( read; echo $REPLY:$$-$BASHPID; )
    4671-5118:4671-5119
    

    Here, the subshell implied by the pipe is explicitly applied, but not duplicated.

    This varies from some other shells that try very hard to avoid fork-ing. Therefore, while I feel the argument made in js-shell-parse misleading, it is true that not all shells always fork for all subshells.

提交回复
热议问题