Bash unsets *_PID variable before I can wait on coproc

bashprocess

I'm trying to use coprocesses to pipe the output of asynchronous processes into other shell commands and then check the exit status of the asynchronous process:

coproc LS { ls dir; }
while IFS= read i; do echo "$i"; done <&"$LS" # Do something with the output.
wait "$LS_PID"; echo $? # Check exit status.

The problem is that the above code does not work, at least not with Bash 4.3.46(1)-release. After the while statement has executed, Bash will unset $LS_PID (probably because it notices that the process has terminated). Calling wait on the processes still works, e.g.:

coproc LS { ls dir; }
P=$LS_PID
while IFS= read i; do echo "$i"; done <&"$LS" # Do something with the output.
wait "$P"; echo $? # Check exit status.

This will print 0 or 2 depending on whether the directory exists. Thus it is just an inconvenience that I have to save the PID to another variable. But I'm interested in why this happens and whether I can influence this.

Why is $LS_PID unset before I wait on the process? Is this behavior documented somewhere? Is there an easy workaround for this, because I think it's a common use case to both use the output of a command and also check its exit code.

Best Answer

This is the intended behaviour of the COPROC_PID variable it seems, though it's undocumented in the Bash manual.

The correct workaround is to do exactly what you've done; save the value of $COPROC_PID in a variable that will not be unset when the co-process exits.

Note that this will not work if the co-process exits before you have time to get it's PID, so it may be prudent to make sure that your variable has a value before you use it.

Reference: http://gnu-bash.2382.n7.nabble.com/Several-issues-with-coprocesses-regarding-exit-status-td11125.html

Related Question