bash coproc和剩余的coproc输出

Jim*_*son 10 bash coproc

我需要在bash脚本中将一些配置数据读入环境变量中.

"明显的"(但不正确)模式是:

egrep "pattern" config-file.cfg | read VAR1 VAR2 VAR3 etc...
Run Code Online (Sandbox Code Playgroud)

这会失败,因为read它在子shell中运行,因此无法在调用shell中设置变量.所以我想出了这个作为替代方案

coproc egrep "pattern" config-file.cfg
read -u ${COPROC[0]} VAR1 VAR2 VAR3 etc...
Run Code Online (Sandbox Code Playgroud)

哪个工作正常.

为了测试如果协同进程返回多行会发生什么,我尝试了这个:

coproc cat config-file.cfg
read -u ${COPROC[0]} VAR1 VAR2 VAR3 etc...
Run Code Online (Sandbox Code Playgroud)

其中config-file.cfg包含三行.

$ cat config-file.cfg
LINE1 A1 B1 C1
LINE2 A2 B2 C2
LINE3 A3 B3 C3
Run Code Online (Sandbox Code Playgroud)

我希望这会处理文件中的第一行,然后是某种"破管"错误消息.虽然它确实处理了第一行,但没有任何错误消息,也没有任何协同进程继续运行.

所以我在脚本中尝试了以下内容:

$ cat test.sh
coproc cat config-file.cfg
read -u ${COPROC[0]} VAR1 VAR2 VAR3 VAR4
echo $VAR1 $VAR2 $VAR3 $VAR4
wait
echo $?
Run Code Online (Sandbox Code Playgroud)

运行它:

$ bash -x test.sh
+ read -u 63 VAR1 VAR2 VAR3 VAR4
+ cat config-file.cfg
LINE1 A1 B1 C1
+ wait
+ echo 0
0
Run Code Online (Sandbox Code Playgroud)

剩下的两条线在哪里?我本来期望要么"断管",要么wait挂起,因为没有什么东西可以读取其余的行,但是你可以看到返回代码为零.

Sha*_*hin 6

根据上面的评论,您可以使用流程替换来实现这一目标.这样,read不会在子shell中运行,捕获的变量将在当前shell中可用.

read VAR1 VAR2 VAR3 < <(egrep "pattern" config-file.cfg)
Run Code Online (Sandbox Code Playgroud)

"如果使用<(list)表单,则应该读取作为参数传递的文件以获取列表的输出" - 作为ag​​rument传递的"文件"他们在谈论什么?

这对我来说也是相当神秘的.Advanced Bash-scripting Guide中有关进程替换章节有更全面的解释.

我看到它的方式,当使用<(cmd)语法时,输出cmd通过命名管道(或临时文件)提供,语法由管道/文件的文件名替换.因此,对于上面的示例,它最终将等同于:

read VAR1 VAR2 VAR3 < /dev/fd/63
Run Code Online (Sandbox Code Playgroud)

/dev/fd/63连接到stdout的命名管道在哪里cmd.