4

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

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

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

我知道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

看来,即使文件中有 4 行,到第二次迭代时,协进程及其文件描述符已经消失,并且${COPROC[*]}变量已变为未设置(注意第二次读取中缺少 fd)。

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

我想这里真正的问题是:

在bash中,我如何完成

while read (list of vars) from file
do
    one or more commands
done

配置文件很短,所以如果我必须将整个文件加载到一个数组中,那就可以了。

我真的很惊讶这在 bash 中如此困难。

4

2 回答 2

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)

当您的输入尚未位于可以使用普通重定向的简单文件中时,这可能会很方便。


如果您想坚持使用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]}
于 2011-10-07T15:10:06.557 回答
2

其中一种语法是:

while read var1 var2 ... ; do
   # one or more commands
done < file
于 2011-10-07T01:27:08.727 回答