Re: Command substitution optimisation in dot scripts
2016-09-30 04:49:33 +0100, Martijn Dekker: [...] > my_subshell_pid=$(sh -c 'echo $PPID') > > This works fine on every shell, except on bash when a dot script is > being executed. [...] While it does look like a bug, you could always do: my_subshell_pid=$(exec sh -c 'echo $PPID') To be sure you know where you stand. bash or other shells could have issues if there's an EXIT trap in place that propagates to subshells or any other reason that prevents them from optimising out the fork. Note that it's the same in: $ bash -c 'p=$(sh -c "echo \"\$PPID\""); echo "$p $BASHPID"' 1513 1512 $ bash -c 'p=$(exec sh -c "echo \"\$PPID\""); echo "$p $BASHPID"' 1515 1515 -- Stephane
Re: Racing condition leads to unstable exit code
On 9/29/16 10:58 PM, Luiz Angelo Daros de Luca wrote: > No problem! I already workarounded it using pipe as a semaphore. Thanks! > > It's there any chance of changing the 128+signal exit code for wait when > trap is received? > It might solve some special usecase which I'm not aware. Wait should always > returns exit code related to the child process, except for 127. The shell is required to do this, and it's historical shell behavior. If a process is killed by signal N, its exit status is 128+N. That's how scripts know their children were killed due to a signal. > The 128+signal behavior is not even mentioned on wait documentation but on > signal section! If wait returns 129, I don't know wether child died because > of signal 1 (128+1) or if it is the current instance that received the > signal instead. Posix says: "When the shell is waiting, by means of the wait utility, for asynchronous commands to complete, the reception of a signal for which a trap has been set shall cause the wait utility to return immediately with an exit status >128, immediately after which the trap associated with that signal shall be taken." If you want the shell to be insulated from signals that might be sent to its children, you either have to use job control, which works for the keyboard-generated signals that go to process groups, or ignore the signal using trap to be sure you don't receive it. Chet -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
Re: Command substitution optimisation in dot scripts
On 9/29/16 11:49 PM, Martijn Dekker wrote: > I detected an oddity (possible bug) in bash: the usual optimisation for > launching external processes in simple command substitutions is turned > off while executing a dot script. > > Background: For reasons that would take too much space to explain here, > I need a cross-platform/POSIX way to get the process ID of the current > subshell. I can't use $BASHPID for this as it's only available on newer > bash (not including the default bash on Mac OS X). > > As far as I know, the canonical cross-platform way of detecting the PID > of a subshell is: > > my_subshell_pid=$(sh -c 'echo $PPID') > > This works fine on every shell, except on bash when a dot script is > being executed. This isn't a bug. It can be viewed as an opportunity for further optimization. Rather than assume an implicit `exec', make your assumption explicit and use something like `exec sh -c 'echo $PPID''. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
Re: Racing condition leads to unstable exit code
Yes, this is the part that I agree. However, this is the other behavior of bash wait (from bash manual) "When Bash is waiting for an asynchronous command via the wait builtin, the reception of a signal for which a trap has been set will cause the wait builtin to return immediately with an exit status greater than 128, immediately after which the trap is executed." The behavior is the same for when parent or child receives the signal. When it's the parent process that received it, child might still be running. It simply breaks the logic of wait. In order to wait until the child exits even when signal was received, I need to implement a new wait command (with some hacks) like this (untested): usr1(){ got_signal=true Do something... } wait2() { while true; do got_signal=false wait $* exitcode=$? $got_signal || return $exitcode } trap usr1 USR1 ( Child stuff... Send USR1 to parent ) & wait2 $! Em sex, 30 de set de 2016 09:45, Chet Ramey escreveu: > On 9/29/16 10:58 PM, Luiz Angelo Daros de Luca wrote: > > No problem! I already workarounded it using pipe as a semaphore. Thanks! > > > > It's there any chance of changing the 128+signal exit code for wait when > > trap is received? > > It might solve some special usecase which I'm not aware. Wait should > always > > returns exit code related to the child process, except for 127. > > The shell is required to do this, and it's historical shell behavior. If > a process is killed by signal N, its exit status is 128+N. That's how > scripts know their children were killed due to a signal. > > > > The 128+signal behavior is not even mentioned on wait documentation but > on > > signal section! If wait returns 129, I don't know wether child died > because > > of signal 1 (128+1) or if it is the current instance that received the > > signal instead. > > Posix says: > > "When the shell is waiting, by means of the wait utility, for asynchronous > commands to complete, the reception of a signal for which a trap has been > set shall cause the wait utility to return immediately with an exit status > >128, immediately after which the trap associated with that signal shall be > taken." > > If you want the shell to be insulated from signals that might be sent to > its children, you either have to use job control, which works for the > keyboard-generated signals that go to process groups, or ignore the signal > using trap to be sure you don't receive it. > > Chet > -- > ``The lyf so short, the craft so long to lerne.'' - Chaucer > ``Ars longa, vita brevis'' - Hippocrates > Chet Ramey, UTech, CWRUc...@case.edu > http://cnswww.cns.cwru.edu/~chet/ > -- Luiz Angelo Daros de Luca luizl...@gmail.com
Re: Racing condition leads to unstable exit code
On 9/30/16 10:11 AM, Luiz Angelo Daros de Luca wrote: > Yes, this is the part that I agree. However, this is the other behavior of > bash wait (from bash manual) > > "When Bash is waiting for an asynchronous command via the wait builtin, the > reception of a signal for which a trap has been set will cause > the wait builtin to return immediately with an exit status greater than > 128, immediately after which the trap is executed." That's pretty much straight out of the portion of the Posix standard I quoted: > Posix says: > > "When the shell is waiting, by means of the wait utility, for asynchronous > commands to complete, the reception of a signal for which a trap has been > set shall cause the wait utility to return immediately with an exit status > >128, immediately after which the trap associated with that signal shall > be > taken." -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
Re: Racing condition leads to unstable exit code
Hi, > Am 30.09.2016 um 16:11 schrieb Luiz Angelo Daros de Luca : > > Yes, this is the part that I agree. However, this is the other behavior of > bash wait (from bash manual) > > "When Bash is waiting for an asynchronous command via the wait builtin, the > reception of a signal for which a trap has been set will cause the wait > builtin to return immediately with an exit status greater than 128, > immediately after which the trap is executed." > > The behavior is the same for when parent or child receives the signal. When > it's the parent process that received it, child might still be running. It > simply breaks the logic of wait. In order to wait until the child exits even > when signal was received, I need to implement a new wait command (with some > hacks) like this (untested): I don't know the process set up you want to achieve, but maybe it helps when you send the signal to the complete process group, and not only the parent process. Specifying a negative PID to `kill` will initiate this. -- Reuti > > usr1(){ > got_signal=true > Do something... > } > > wait2() { > while true; do > got_signal=false > wait $* > exitcode=$? > $got_signal || return $exitcode > } > > trap usr1 USR1 > > ( Child stuff... Send USR1 to parent ) & > wait2 $! > > > > Em sex, 30 de set de 2016 09:45, Chet Ramey escreveu: > On 9/29/16 10:58 PM, Luiz Angelo Daros de Luca wrote: > > No problem! I already workarounded it using pipe as a semaphore. Thanks! > > > > It's there any chance of changing the 128+signal exit code for wait when > > trap is received? > > It might solve some special usecase which I'm not aware. Wait should always > > returns exit code related to the child process, except for 127. > > The shell is required to do this, and it's historical shell behavior. If > a process is killed by signal N, its exit status is 128+N. That's how > scripts know their children were killed due to a signal. > > > > The 128+signal behavior is not even mentioned on wait documentation but on > > signal section! If wait returns 129, I don't know wether child died because > > of signal 1 (128+1) or if it is the current instance that received the > > signal instead. > > Posix says: > > "When the shell is waiting, by means of the wait utility, for asynchronous > commands to complete, the reception of a signal for which a trap has been > set shall cause the wait utility to return immediately with an exit status > >128, immediately after which the trap associated with that signal shall be > taken." > > If you want the shell to be insulated from signals that might be sent to > its children, you either have to use job control, which works for the > keyboard-generated signals that go to process groups, or ignore the signal > using trap to be sure you don't receive it. > > Chet > -- > ``The lyf so short, the craft so long to lerne.'' - Chaucer > ``Ars longa, vita brevis'' - Hippocrates > Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/ > -- > Luiz Angelo Daros de Luca > luizl...@gmail.com >
Re: Command substitution optimisation in dot scripts
On 9/29/16 11:49 PM, Martijn Dekker wrote: > I detected an oddity (possible bug) in bash: the usual optimisation for > launching external processes in simple command substitutions is turned > off while executing a dot script. Thanks for the suggestion. I added the optimization to command substitution in the presence of `.' and eval. Chet -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/