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