Is there a subshell created when I run `sh -c “command”`, a new shell or none of these?

后端 未结 7 723
醉话见心
醉话见心 2020-12-08 23:18

In bash, when I run the following command:

sh -c \"command\"

is there created a subshell and then the command

7条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-08 23:22

    Regardless bash

    Running this simple line will show you a lot:

    $ echo $$;sh -c 'echo $$;ps axfw | grep -B2 $$'
    14152
    12352
    14147 ?        S      0:00 xterm
    14152 pts/4    Ss     0:00  \_ bash
    12352 pts/4    S+     0:00      \_ sh -c echo $$;ps axfw | grep -B2 $$
    12353 pts/4    R+     0:00          \_ ps axfw
    12354 pts/4    S+     0:00          \_ grep -B2 12352
    

    This is clearly a child but what's a subshell?

    Well, my current running shell pid is 14152

    $ echo $$ $BASHPID $BASH_SUBSHELL 
    14152 14152 0
    $ (echo $$ $BASHPID $BASH_SUBSHELL)
    14152 12356 1
    $ ( (echo $$ $BASHPID $BASH_SUBSHELL) )
    14152 12357 2
    

    Well nice: BASHPID is a dynamic variable which take alway the value of executing pid:

    $ echo $BASHPID | sed \$a$BASHPID | sed \$a$BASHPID
    12371
    12372
    12373
    

    Hmmm where is my current working pid?

    $ sed "\$a$BASHPID $$" < <(echo "$BASHPID $$"| sed "\$a$BASHPID $$")
    12386 14152
    12387 14152
    14152 14152
    

    Well I've find them!

    $ echo $BASHPID $$;(echo $BASHPID $$;ps axfw | grep -B3 $BASHPID)
    14152 14152
    12469 14152
    14152 pts/4    Ss     0:00  \_ bash
    12469 pts/4    S+     0:00      \_ bash
    12470 pts/4    R+     0:00          \_ ps axfw
    12471 pts/4    S+     0:00          \_ grep -B3 12471
    

    Conclusion

    When you

    $ echo $BASHPID $$ $BASH_SUBSHELL;(echo $BASHPID $$ $BASH_SUBSHELL)
    14152 14152 0
    12509 14152 1
    

    use parenthesis or pipe (|), you will create subshell which is a forked child of a running shell.

    But when you

    $ echo $BASHPID $$ $BASH_SUBSHELL;bash -c 'echo $BASHPID $$ $BASH_SUBSHELL'
    14152 14152 0
    12513 12513 0
    

    You will burn a child, running a shell interpreter, so it's a subshell, but not linked to his parent.

    Nota: If the child is not linked to his parent, they use same I/O files descriptors. So if you close your window (pts/4 in my run), you will send a SIGHUP to all process using them.

提交回复
热议问题