更多coproc问题

Jim*_*son 4 bash coproc

这是bash coproc和剩余coproc输出的后续

我最终决定一次处理一行文件的成语是:

coproc cat auto/etc/build.cfg
while read -u ${COPROC[0]} BRANCH TARGET SVNSRC SVNTAG BUILDTYPE DISTTYPE DISTARGS
do
    ... commands ...
done
Run Code Online (Sandbox Code Playgroud)

我知道简单的情况cat我可以使用输入重定向.这是一个简化版本,其中真实版本使用egrep来选择行的子集.

不幸的是,这不起作用.

$ cat test.sh
coproc cat auto/etc/build.cfg
while read -u ${COPROC[0]} BRANCH TARGET SVNSRC SVNTAG BUILDTYPE DISTTYPE DISTARGS
do
    echo hello
done

$ bash -x test.sh
+ read -u 63 BRANCH TARGET SVNSRC SVNTAG BUILDTYPE DISTTYPE DISTARGS
+ cat auto/etc/build.cfg
+ echo hello
hello
+ read -u BRANCH TARGET SVNSRC SVNTAG BUILDTYPE DISTTYPE DISTARGS
test.sh: line 2: read: BRANCH: invalid file descriptor specification
Run Code Online (Sandbox Code Playgroud)

看起来,即使文件中有4行,到第二次迭代时,协同处理已经消失,连同其文件描述符,并且${COPROC[*]}变量已经未设置(请注意第二次读取中缺少的fd).

更复杂的是,我在Cygwin和Linux(Fedora)中工作,这在两种环境中表现出略微不同的行为.在Linux中,我得到了上述行为.在Cygwin中,一些命令(即echo内置的bash)不会导致此问题.在这两种环境中,运行任何外部命令都会杀死协同进程并抛出其描述符.

我想这里真正的问题是:

在bash中,我该如何完成

while read (list of vars) from file
do
    one or more commands
done
Run Code Online (Sandbox Code Playgroud)

配置文件很短,所以如果我必须将整个文件加载到一个数组中,那将是有效的.

我真的很惊讶这在bash中如此之难.

Chr*_*sen 5

我不确定为什么你的使用coproc不起作用.您的示例适用于Mac OS X上的bash 4.2.8.也许某些版本的bash在这里有错误.

听起来你可以从进程替换重定向而不是使用协同进程.

while read foo bar baz quux; do
    : use foo, bar, baz, quux in various commands
done < <(commands | that | generate --your lines-to-read)
Run Code Online (Sandbox Code Playgroud)

当您的输入不在可以使用普通重定向的简单文件中时,这可能很方便.


如果你想坚持下去coproc,你可能可以使用替代配方:

coproc { commands | that | generate --your lines-to-read ; }
while read foo bar baz quux; do
    : use foo, bar, baz, quux in various commands
done <&${COPROC[0]}
Run Code Online (Sandbox Code Playgroud)