Question

In the following test script I run an elementary coprocess to which the echo built-in, run in background, attaches its standard-output:

#!/bin/bash
# TEST 1
coproc /bin/sleep 100
echo >&${COPROC[1]} &

The script always fails, for no apparent reason, giving the output:

./test.sh: line 4: ${COPROC[1]}: Bad file descriptor

I wonder if the correct syntax should be rather this one (ampersand moved before redirection):

#!/bin/bash
# TEST 2
coproc /bin/sleep 100
echo & >&${COPROC[1]}

This second example seems to work since it reports no errors during execution, but with this syntax, the redirection is not performed in practice; in fact, consider this other test:

#!/bin/bash
# TEST 3
/bin/echo abc & >xfile

Test 3 creates the file xfile, but does not write anything into it. Curiously, trying again to position the ampersand after the redirection make the echo work fine:

#!/bin/bash
# TEST 4
/bin/echo abc >xfile &

Test 4 creates the file xfile with inside the string abc.

Have some idea on what is causing the coproc redirection error or what the correct syntax is?

Was it helpful?

Solution

You've got the answer elsewhere http://lists.gnu.org/archive/html/bug-bash/2012-06/msg00027.html:

Coproc file descriptors are not available to subshells. They're implemented using pipes, and leaving pipe file descriptors open in subshells causes processes to hang and not terminate properly, which results in very hard-to-track-down-and-reproduce bugs.

OTHER TIPS

As noted elsewhere, coproc arranges for its filedescriptors to be closed in subshells. You can get around that using

coproc { whatever; }
exec {WHATEVER[0]}<&${COPROC[0]}- {WHATEVER[1]}>&${COPROC[1]}-

If using Bash prior to version 4.3 you'll have to use separate variables for the input & output variables:

exec {IN}<&${COPROC[0]}- {OUT}>&${COPROC[1]}-

If using Bash prior to 4.1, you'll have to make do with fixed filedescriptor numbers:

exec 4<&${COPROC[0]}- 5>&${COPROC[1]}- ; IN=4 OUT=5

For an interactive shell you might want to consider disown.

This arrangement also has the benefit that you can use more than one coprocess, even though the Bash man page says that it's not supported.

And as discussed elsewhere, be aware of the limitations of sharing pipes between processes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top