bash的协处理器和吃剩的协处理器输出 [英] bash coproc and leftover coproc output

查看:204
本文介绍了bash的协处理器和吃剩的协处理器输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在bash脚本阅读一些配置数据为环境变量。

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

  egrep的模式配置,file.cfg |阅读VAR1 VAR2 VAR3等..

这将会失败,因为运行在子shell,因此不能在调用shell设置变量。所以,我想出了这个作为一种替代

 协处理器egrep的模式配置,file.cfg
阅读-u $ {协处理器[0]} VAR1 VAR2 VAR3等..

这工作得很好。

要测试是否协进程返回多个行会发生什么,我想这一点:

 协处理器猫的配置,file.cfg
阅读-u $ {协处理器[0]} VAR1 VAR2 VAR3等..

其中,配置 - file.cfg 包含三行。

  $猫的配置,file.cfg
LINE1 A1 B1 C1
LINE2 A2 B2 C2
LINE3 A3 B3 C3

我预计在处理文件的第一行,其次是某种断管的错误消息。虽然它的没有过程中的第一行,没有出现错误信息,但协同进程留下的运行。

于是,我又试图在脚本如下:

  $猫test.sh
协处理器猫的配置,file.cfg
阅读-u $ {协处理器[0]} VAR1 VAR2 VAR3 VAR4
回声$ VAR1 $ VAR2 $ VAR3 $ VAR4
等待
回声$?

运行它:

  $ bash的-x test.sh
+阅读-u 63 VAR1 VAR2 VAR3 VAR4
+猫的配置,file.cfg
LINE1 A1 B1 C1
+等待
+ 0呼应
0

在哪里其余两条线走?我本来期望无论是破管道,或,因为没有什么可以读取剩余的线条,但你可以看到返回code是挂零。


解决方案

根据上述意见,你可以使用的进程替换来实现这一点。这样一来,不是在子shell中运行,并且拍摄的增值经销商将在当前shell中是可用的。

 阅读VAR1 VAR2 VAR3< ≤(egrep的模式配置,file.cfg)



  

如果<使用(清单)的形式,作为参数传递的文件应被理解为获取列表的输出? - 什么为agrument传递文件他们在谈论


这是相当神秘的对我来说太。该在高级Bash脚本编程指南进程替换章节都有多个COM prehensive解释。

路上,我看到它,当≤(CMD)语法时, CMD 的输出中通过命名管道(或临时文件)提供和语法由管/文件的文件名取代。因此,对于上面的例子,这将最终被等同于:

 阅读VAR1 VAR2 VAR3<为/ dev / FD / 63

其中,的/ dev / FD / 63 是连接到标准输出 CMD 的命名管道。

I need to read some configuration data into environment variables in a bash script.

The "obvious" (but incorrect) pattern is:

egrep "pattern" config-file.cfg | read VAR1 VAR2 VAR3 etc...

This fails because the read is run in a subshell and therefore cannot set variables in the invoking shell. So I came up with this as an alternative

coproc egrep "pattern" config-file.cfg
read -u ${COPROC[0]} VAR1 VAR2 VAR3 etc...

which works fine.

To test what happens if the coprocess returns more than one line, I tried this:

coproc cat config-file.cfg
read -u ${COPROC[0]} VAR1 VAR2 VAR3 etc...

where config-file.cfg contains three lines.

$ cat config-file.cfg
LINE1 A1 B1 C1
LINE2 A2 B2 C2
LINE3 A3 B3 C3

I expected this to process the first line in the file, followed by some kind of "broken pipe" error message. While it did process the first line, there was no error message and no coprocess was left running.

So I then tried the following in a script:

$ cat test.sh
coproc cat config-file.cfg
read -u ${COPROC[0]} VAR1 VAR2 VAR3 VAR4
echo $VAR1 $VAR2 $VAR3 $VAR4
wait
echo $?

Running it:

$ bash -x test.sh
+ read -u 63 VAR1 VAR2 VAR3 VAR4
+ cat config-file.cfg
LINE1 A1 B1 C1
+ wait
+ echo 0
0

Where did the remaining two lines go? I would have expected either "broken pipe", or the wait to hang since there was nothing to read the remaining lines, but as you can see the return code was zero.

解决方案

As per comments above, you can use process substitution to achieve just that. This way, read is not run in a subshell and the captured vars will be available within the current shell.

read VAR1 VAR2 VAR3 < <(egrep "pattern" config-file.cfg)


"If the <(list) form is used, the file passed as an argument should be read to obtain the output of list" -- what "file passed as an agrument" are they talking about?

That is rather cryptic to me too. The chapter on process substitution in Advanced Bash-scripting Guide has a more comprehensive explanation.

The way I see it, when the <(cmd) syntax is used, the ouput of cmd is made available via a named pipe (or temp file) and the syntax is replaced by the filename of the pipe/file. So for the example above, it would end up being equivalent to:

read VAR1 VAR2 VAR3 < /dev/fd/63

where /dev/fd/63 is the named pipe connected to the stdout of cmd.

这篇关于bash的协处理器和吃剩的协处理器输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆