Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: msys Compiler: gcc Compilation CFLAGS: -g -O2 uname output: MSYS_NT-10.0-19045 Zack2021HPPavilion 3.5.3-d8b21b8c.x86_64 2024-07-09 18:03 UTC x86_64 Msys Machine Type: x86_64-pc-msys
Bash Version: 5.3 Patch Level: 0 Release Status: alpha Fix: diff --git a/general.c b/general.c index 5c26ae38..723607eb 100644 --- a/general.c +++ b/general.c @@ -834,7 +834,7 @@ absolute_program (const char *string) return ((char *)mbschr (string, '/') != (char *)NULL); #else return ((char *)mbschr (string, '/') != (char *)NULL || - (char *)mbschr (string, '\\') != (char *)NULL) + (char *)mbschr (string, '\\') != (char *)NULL); #endif } On Tue, Jul 9, 2024 at 2:37 PM Zachary Santer <zsan...@gmail.com> wrote: > > On the other hand, do funsubs give us the answer here? > > shopt -s lastpipe > declare -a pid=() > command-1 | tee >( command-2 ) ${ pid+=( "${!}" ); } >( command-3 ) ${ > pid+=( "${!}" ); } >( command-4 ) ${ pid+=( "${!}" ); } > wait -- "${pid[@]}" This absolutely works, so there you go. When expanding multiple process substitutions as arguments to a command, you can save the $! resulting from each one by following it with an unquoted funsub that does that work and doesn't expand to anything. > That looks obnoxious I don't mind how it looks. It works. > declare -a pid=() > { > commands > } {fd[0]}< <( command-1 ) ${ pid+=( "${!}" ); } {fd[1]}< <( command-2 > ) ${ pid+=( "${!}" ); } {fd[2]}< <( command-3 ) ${ pid+=( "${!}" ); } > > Do things start breaking? Yeah, this doesn't work at all, but whatever. You can get the same result by performing each redirection with exec individually, followed by saving $! somewhere. I want to say that expanding multiple process substitutions as arguments to a single command was the one situation where you couldn't arrange things such that you can save $! after each time a process substitution is expanded, and funsubs seem to have solved that problem. I won't be offended if there's still no mechanism to tell the running script about pids of multiple child processes at the same time, when later versions of bash come out. Description: See my attachments, though. Something about my second set of process substitutions is causing 'wait' without arguments to not wait for the final procsub, whose pid is still in $! at the time. Repeat-By: procsub-wait-solution false On Fri, Jul 5, 2024 at 2:38 PM Chet Ramey <chet.ra...@case.edu> wrote: > > There is code tagged > for bash-5.4 that allows `wait -n' to look at these exited processes as > long as it's given an explicit set of pid arguments. I agree with all the knowledgeable people here telling you that the way 'wait -n' is still implemented in bash-5.3-alpha is obviously wrong, but I also want to point out that the way you plan to change its behavior in bash-5.4 still won't allow Greg's example below to work reliably. On Fri, Jul 12, 2024 at 9:06 PM Greg Wooledge <g...@wooledge.org> wrote: > > greg@remote:~$ cat ~greybot/factoids/wait-n; echo > Run up to 5 processes in parallel (bash 4.3): i=0 j=5; for elem in > "${array[@]}"; do (( i++ < j )) || wait -n; my_job "$elem" & done; wait He'd have to do something like this: set -o noglob i=0 j=5 declare -a pid_set=() for elem in "${array[@]}"; do if (( ! i++ < j )); then wait -n -p terminated_pid -- "${!pid_set[@]}" unset pid_set[terminated_pid] fi my_job "$elem" & pid_set[${!}]='' done wait It's probably best that 'wait -n' without arguments and 'wait -n' with explicit pid arguments have the same relationship to each other as 'wait' without arguments and 'wait' with explicit pid arguments. In other words, process substitutions notwithstanding, $ wait and $ wait -- "${all_child_pids[@]}" do the same thing. So, $ wait -n and $ wait -n -- "${all_child_pids[@]}" should also do the same thing.
zsant@Zack2021HPPavilion MSYS ~/repos/bash $ ./bash.exe ~/random/procsub-wait-solution true + : '5.3.0(1)-alpha' + wait_explicit_pids=true + pid=() + declare -a pid ++ sleep 8 ++ pid+=(${!}) ++ sleep 6 ++ pid+=(${!}) ++ sleep 4 ++ pid+=(${!}) ++ sleep 2 ++ pid+=(${!}) + : /dev/fd/63 /dev/fd/62 /dev/fd/61 /dev/fd/60 + SECONDS=0 + : 'declare -a pid=([0]="20370" [1]="20371" [2]="20372" [3]="20373")' '$!=20373' + [[ true == true ]] + wait -- 20370 20371 20372 20373 + : termination status 0 at 8 seconds + pid=() + printf 'The quick brown fox jumps over the lazy dog.\n' ++ set +x ++ pid+=(${!}) ++ set +x ++ pid+=(${!}) ++ set +x ++ pid+=(${!}) ++ set +x ++ pid+=(${!}) + tee -- /dev/fd/63 /dev/fd/62 /dev/fd/61 /dev/fd/60 The quick brown fox jumps over the lazy dog. + SECONDS=0 + : 'declare -a pid=([0]="20375" [1]="20376" [2]="20377" [3]="20378")' '$!=20378' + [[ true == true ]] + wait -- 20375 20376 20377 20378 overly emphatic : The. Quick. Brown. Fox. Jumps. Over. The. Lazy. Dog. shouting : THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. tortoise, actually : The quick brown fox jumps over the lazy tortoise. line length : 44 + : termination status 0 at 8 seconds + : This breaks, but that is fine. + pid=() + fd=() + declare -a fd /home/zsant/random/procsub-wait-solution: line 65: syntax error near unexpected token `${ pid+=(${!}); }' /home/zsant/random/procsub-wait-solution: line 65: `{ :; } {fd[0]}< <( sleep 4; ) ${ pid+=( ${!} ); } \' zsant@Zack2021HPPavilion MSYS ~/repos/bash $ ./bash.exe ~/random/procsub-wait-solution false + : '5.3.0(1)-alpha' + wait_explicit_pids=false + pid=() + declare -a pid ++ sleep 8 ++ pid+=(${!}) ++ sleep 6 ++ pid+=(${!}) ++ sleep 4 ++ pid+=(${!}) ++ sleep 2 ++ pid+=(${!}) + : /dev/fd/63 /dev/fd/62 /dev/fd/61 /dev/fd/60 + SECONDS=0 + : 'declare -a pid=([0]="20385" [1]="20386" [2]="20387" [3]="20388")' '$!=20388' + [[ false == true ]] + wait + : termination status 0 at 2 seconds + pid=() + printf 'The quick brown fox jumps over the lazy dog.\n' ++ set +x ++ pid+=(${!}) ++ set +x ++ pid+=(${!}) ++ set +x ++ pid+=(${!}) ++ set +x ++ pid+=(${!}) + tee -- /dev/fd/63 /dev/fd/62 /dev/fd/61 /dev/fd/60 The quick brown fox jumps over the lazy dog. + SECONDS=0 + : 'declare -a pid=([0]="20390" [1]="20391" [2]="20392" [3]="20393")' '$!=20393' + [[ false == true ]] + wait + : termination status 0 at 0 seconds + : This breaks, but that is fine. + pid=() + fd=() + declare -a fd /home/zsant/random/procsub-wait-solution: line 65: syntax error near unexpected token `${ pid+=(${!}); }' /home/zsant/random/procsub-wait-solution: line 65: `{ :; } {fd[0]}< <( sleep 4; ) ${ pid+=( ${!} ); } \' zsant@Zack2021HPPavilion MSYS ~/repos/bash $ overly emphatic : The. Quick. Brown. Fox. Jumps. Over. The. Lazy. Dog. shouting : THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. tortoise, actually : The quick brown fox jumps over the lazy tortoise. line length : 44
procsub-wait-solution
Description: Binary data