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

Attachment: procsub-wait-solution
Description: Binary data

Reply via email to