Re: forked before bash subshell

2016-10-13 Thread Daniel Colascione

On 10/13/2016 08:05 PM, Bob Proulx wrote:

XiaoBing Jiang wrote:

Greg Wooledge wrote:

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 ?


Because it wouldn't save anything significant.  Since the parent shell
is bash the extra bash in memory is already in memory.  A forked
process uses almost the same OS memory as the original.  The OS will
share the code pages between the two processes at the OS memory page
level.  Data pages will split when they are individually modified.
Even if you use 'exec' to replace the forked and backgrounded copy
another one is still in memory as the script runs.  Only unique data
pages will go through the copy-on-write process as the two bash
processes diverge.  Therefore even if you *think* you are saving
something by optimizing it out the actual savings is insignificantly
small.

Plus this is really only a problem if the main part of the script
exits leaving the forked subshell running in the background.  However
that is not a good thing to do.  If you want to leave the process
running that is a daemon process.  Launching a daemon process needs
more setup than this to avoid other problems.  Since leaving processes
behind like that is a bad thing to do it again doesn't make much sense
to try to optimize the doing of it.

It is possible to contrive some examples where it makes sense to do
this optimization.  But mostly they are very unusual cases.  Not
typical cases.


One such case is Cygwin --- I'm not sure how "contrived" it is. Cygwin 
has an old-fashioned non-COW fork, and to add insult to injury, process 
creation generally is very slow (~100ms). It pays to eliminate subshells 
in that environment.




Re: forked before bash subshell

2016-10-13 Thread Bob Proulx
XiaoBing Jiang wrote:
> Greg Wooledge wrote:
> > 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 ?

Because it wouldn't save anything significant.  Since the parent shell
is bash the extra bash in memory is already in memory.  A forked
process uses almost the same OS memory as the original.  The OS will
share the code pages between the two processes at the OS memory page
level.  Data pages will split when they are individually modified.
Even if you use 'exec' to replace the forked and backgrounded copy
another one is still in memory as the script runs.  Only unique data
pages will go through the copy-on-write process as the two bash
processes diverge.  Therefore even if you *think* you are saving
something by optimizing it out the actual savings is insignificantly
small.

Plus this is really only a problem if the main part of the script
exits leaving the forked subshell running in the background.  However
that is not a good thing to do.  If you want to leave the process
running that is a daemon process.  Launching a daemon process needs
more setup than this to avoid other problems.  Since leaving processes
behind like that is a bad thing to do it again doesn't make much sense
to try to optimize the doing of it.

It is possible to contrive some examples where it makes sense to do
this optimization.  But mostly they are very unusual cases.  Not
typical cases.

Bob



Re: The "-e" test ingores broken links

2016-10-13 Thread Peter & Kelly Passchier
WHich docs?
If I do "help test" it states: "All file operators except -h and -L are
acting on the target of a symbolic link, not on the symlink itself, if
FILE is a symbolic link."

Peter

On 14/10/2559 02:00, Łukasz Grabowski wrote:
> Configuration Information [Automatically generated, do not change]:
> Machine: i586
> OS: linux-gnu
> Compiler: gcc
> Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='i586'
> -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i586-pc-linux-gnu'
> -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash'
> -DSHELL -DHAVE_CON
> FIG_H   -I.  -I../. -I.././include -I.././lib  -D_FORTIFY_SOURCE=2 -g
> -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wall
> uname output: Linux brutus 3.16.0-4-686-pae #1 SMP Debian
> 3.16.36-1+deb8u1 (2016-09-03) i686 GNU/Linux
> Machine Type: i586-pc-linux-gnu
> 
> Bash Version: 4.3
> Patch Level: 30
> Release Status: release
> 
> Description:
> according to docs -e test should return true when tested on files,
> including broken links, but it doesn't
> 
> Repeat-By:
> the two commands
> ln -s xxx a
> if [ -e a ]; then echo "exists!"; fi
> don't produce any output on my system
> 
> 
> Best,
> Łukasz Grabowski
> 




The "-e" test ingores broken links

2016-10-13 Thread Łukasz Grabowski
Configuration Information [Automatically generated, do not change]:
Machine: i586
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='i586'
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i586-pc-linux-gnu'
-DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash'
-DSHELL -DHAVE_CON
FIG_H   -I.  -I../. -I.././include -I.././lib  -D_FORTIFY_SOURCE=2 -g
-O2 -fstack-protector-strong -Wformat -Werror=format-security -Wall
uname output: Linux brutus 3.16.0-4-686-pae #1 SMP Debian
3.16.36-1+deb8u1 (2016-09-03) i686 GNU/Linux
Machine Type: i586-pc-linux-gnu

Bash Version: 4.3
Patch Level: 30
Release Status: release

Description:
according to docs -e test should return true when tested on files,
including broken links, but it doesn't

Repeat-By:
the two commands
ln -s xxx a
if [ -e a ]; then echo "exists!"; fi
don't produce any output on my system


Best,
Łukasz Grabowski



Re: forked before bash subshell

2016-10-13 Thread XiaoBing Jiang
On Wed, Oct 12, 2016 at 8:23 PM, Greg Wooledge  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 ttys0150:00.00 bash t.sh
> >   501 50275 50181   0 10:10AM ttys0150: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/5Ss 0:00 bash
> 20165 pts/5R+ 0:00  \_ ps f -t pts/5
> 20160 pts/5S  0:00 /bin/bash ./foo
> 20161 pts/5S  0:00  \_ sleep 20
>
> You will have:
>
> $ ./foo
> end
> $ ps f -t pts/5
>   PID TTY  STAT   TIME COMMAND
>  7287 pts/5Ss 0:00 bash
> 20173 pts/5R+ 0:00  \_ ps f -t pts/5
> 20172 pts/5S  0:00 sleep 20
>
> This is what you wanted, right?
>


Re: BASH_SUBSHELL reset to 0 on EXIT trap in aubshell

2016-10-13 Thread Martijn Dekker
Also, perhaps BASH_SUBSHELL should be a readonly like BASHPID is.

- M.



BASH_SUBSHELL reset to 0 on EXIT trap in aubshell

2016-10-13 Thread Martijn Dekker
bash resets BASH_SUBSHELL to 0 when executing an EXIT trap, even if the
EXIT trap is executed in a subshell.

echo $(trap 'echo $BASH_SUBSHELL' EXIT; echo $BASH_SUBSHELL)
Actual output: 1 0
Expected output: 1 1

The same does not happen for a signal trap.

echo $(trap 'echo $BASH_SUBSHELL; exit' INT; echo $BASH_SUBSHELL;
   kill -s INT $BASHPID)
Actual output: 1 1
Expected output: 1 1

Thanks,

- Martijn