这是bash coproc and leftover coproc output
的后续内容我最终决定一次处理一行文件的成语是:
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中,一些命令(即echo
(内置bash)不会导致此问题。在这两种环境中,运行任何外部命令都会杀死协同进程并抛出其描述符。
我想这里真正的问题是:
在bash中,我该如何完成
while read (list of vars) from file
do
one or more commands
done
配置文件很短,所以如果我必须将整个文件加载到一个数组中,那就可以了。
我真的很惊讶在bash中这太难了。
答案 0 :(得分: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]}
答案 1 :(得分:2)
其中一个语法是:
while read var1 var2 ... ; do
# one or more commands
done < file