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; }
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.

  • 1
    Same behaviour with Bash 4.4.5(1)-release. I can not find this documented anywhere. – Kusalananda Jan 13 '17 at 14:40

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

  • 1
    Or use $! instead of $LS_PID which doesn't have the problem. Note that it's the same with the $LS variable. Probably better to give up on coprocs in bash or use a shell with a proper coproc implementation, or avoids coproc altogether as most often there's a better way to do things. See How do you use the command coproc in Bash? – Stéphane Chazelas May 9 '17 at 13:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.