0

I don't understand this sentence about Coprocesses in the bash man page:

Since the coprocess is created as an asynchronous command, the coproc command always returns success. The return status of a coprocess is the exit status of 'command'.

What is the difference between a "success" return value and a "success/error" (0/non-0) exit status? How differently are they handled by the bash? And how can one catch them to see the difference?

The Quark
  • 260
  • 1
  • 11
  • 1
    They're the same thing, but I think what you're missing is that the two sentences are talking about return statuses of different things. The first line is about the `coproc` command itself, and the second line is about the process started by `coproc`. – muru Sep 19 '21 at 00:09
  • @muru I see now, I was mixing up **return value** (as in *exit status*) and **output** (as in *standard output* or *stdout*) – The Quark Sep 20 '21 at 15:04

1 Answers1

2

To get the exit status of the command you need to wait on its process id. You can see this and the difference between the statuses with this example:

coproc mytr { tr a b; exit 2; }
rc=$? fdi=${mytr[0]} fdo=${mytr[1]} pid=$mytr_PID
echo "rc=$rc fdi=$fdi fdo=$fdo pid=$pid"
echo aaa >&$fdo
exec {fdo}>&- 
cat -v <&$fdi
wait $pid
echo $?

We start a named coproc mytr which translates a to b and after reading eof exits with return code 2. The following echo shows that this coproc command has a return code of 0, success, and that bash has set array mytr to the in and out file descriptors to the process. The pid is in variable mytr_PID which we copy as it will disappear when the co-process ends.

We send the string "aaa" to the coproc, then close the input fd with syntax {variable}>&-. We read the output of the tr command, which is "bbb", and then wait for the process to exit. The exit code of wait is the exit code of the process. The output is

rc=0 fdi=63 fdo=60 pid=8137
bbb
2

Note: fdo and fdi are as seen by the parent process, hence echo to fdo is output to the child coprocess's input.

meuh
  • 49,672
  • 2
  • 52
  • 114
  • Do I understand it correctly that when `wait $pid` is called, the coprocess is in fact already terminated, but its exit status can still be passed on to the exit status of the `wait` command? – The Quark Sep 19 '21 at 12:06
  • 1
    Yes, I suppose bash must hold on to the exit status of all background children in case there is a wait. You can add a sleep between the tr and the exit in the coproc if you want to see it really wait, but you will have to remove the cat too as it will evidently wait until eof. Or replace it by a short read like `dd count=1 bs=1`. – meuh Sep 19 '21 at 12:11
  • Do you mind if I edit your answer to make it clearer (for instance currently both the subshell coprocess and the command running inside the subshell coprocess bear the same name `tr`, although they are different processes as seen from a `ps` command). – The Quark Sep 20 '21 at 14:10
  • I usually name things `my...` in examples, so I've updated the example with `mytr`, and also used the simpler variables fdo, fdi instead of the array. You can edit it further if this didn't address your problems, as this will probably help others. Can we also remove the first 4 comments above to clean up a bit? – meuh Sep 20 '21 at 14:40