Re: forked before bash subshell
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
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
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
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
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
Also, perhaps BASH_SUBSHELL should be a readonly like BASHPID is. - M.
BASH_SUBSHELL reset to 0 on EXIT trap in aubshell
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