On Wed, Oct 12, 2016 at 8:23 PM, Greg Wooledge <wool...@eeg.ccf.org> wrote:

> On Tue, Oct 11, 2016 at 07:14:24PM -0700, s7v7nisla...@gmail.com wrote:
> > why bash bahavior like this? is that a bug?
> >
> > if not, why should forked before execute subshell?
>
> Because that's how subshells work.  A subshell *is* a fork.
>
> > 1. the script to reproduce
> > bash-4.4$ cat t.sh
> > (cd /tmp && sleep 20) &
> >
> > echo "end"
>
> When executing the first line:
>
> 1) Bash (the parent) forks.
> 2) The child executes the compound command: cd /tmp && sleep 20
>    2a) The child process uses chdir() to change directory.
>    2b) The child proesss forks and execs and waits for the external
> command:
>        sleep 20
> 3) Since the subshell is running in the background, the parent Bash
>    continues on to execute: echo "end"
> 4) The parent Bash exits.  The child which is waiting for sleep 20 to
>    terminate continues running.  sleep 20 also continues running.
>
> > 3. script end, but there is a new forked script.
> > bash-4.4$ ps -ef | grep t.sh
> >   501 50268     1   0 10:09AM ttys015    0:00.00 bash t.sh
> >   501 50275 50181   0 10:10AM ttys015    0:00.00 grep t.sh
>
> Process 50268 is the child which is waiting for sleep 20 to finish.
>
> > question:
> > when using sh -> dash, It will not fork before subshell, what's the
> different?
>
> Dash probably optimizes the compound command inside the subshell more
> aggressively than bash does.  It may implicitly exec for you.
>
> If you want to ENSURE that the child shell process is replaced by the
> external sleep 20, use an explicit exec.
>
>
yes, I want to know why bash not optimize this. or any strategy ?

Thank you for your explain!


> #!/bin/bash
> (cd /tmp && exec sleep 20) &
> echo "end"
>
> Then, instead of having:
>
> $ ./foo
> end
> $ ps f -t pts/5
>   PID TTY      STAT   TIME COMMAND
>  7287 pts/5    Ss     0:00 bash
> 20165 pts/5    R+     0:00  \_ ps f -t pts/5
> 20160 pts/5    S      0:00 /bin/bash ./foo
> 20161 pts/5    S      0:00  \_ sleep 20
>
> You will have:
>
> $ ./foo
> end
> $ ps f -t pts/5
>   PID TTY      STAT   TIME COMMAND
>  7287 pts/5    Ss     0:00 bash
> 20173 pts/5    R+     0:00  \_ ps f -t pts/5
> 20172 pts/5    S      0:00 sleep 20
>
> This is what you wanted, right?
>

Reply via email to