Background process redirect to COPROC

喜夏-厌秋 提交于 2020-01-04 11:04:28

问题


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?


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/10867153/background-process-redirect-to-coproc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!