bash的协处理器 - 意外的行为 [英] bash coproc - unexpected behavior

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

问题描述

跟进到

  • More coproc questions
  • bash coproc and leftover coproc output

既然如我所料明显的使用协处理器不工作,如看到:

Given that the obvious use of coproc does not work as I expected, as seen in:

$ 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

问:为什么协处理器去后脚本走读取一行输出

Question: Why does the coproc go away after the script reads one line of output?

推荐答案

我无法重现:

bash-4.1 $ cat infile 
one
two
three
four
five

bash-4.1 $ cat s.sh 
coproc cat infile
while read -u ${COPROC[0]} v; do
  echo "$v"
done

bash-4.1 $ bash -x s.sh 
+ read -u 63 v
+ cat infile
+ echo one
one
+ read -u 63 v
+ echo two
two
+ read -u 63 v
+ echo three
three
+ read -u 63 v
+ echo four
four
+ read -u 63 v
+ echo five
five
+ read -u 63 v
+ echo ''

+ read -u 63 v

编辑:我没有重现这样的:

I did reproduce it like this:

bash-4.1 $ cat s.sh 
coproc cat infile

sleep 1

while read -u ${COPROC[0]} v; do
  echo "$v"
done

bash-4.1 $ bash  -x s.sh 
+ sleep 1
+ cat infile
+ read -u v
s.sh: line 5: read: v: invalid file descriptor specification

编辑:请参阅下面的注释

See comments below.

看来,合作进程超时迅速...
可能是你的系统很慢:)

It seems that the co-process times out quickly ... May be your system is slow :)

没有,执行的命令作为共同的过程太快,
如果你慢下来,它的工作原理:

No, the command executed as co-process is too quick, if you slow it down, it works:

bash-4.1 $ cat s.sh 
coproc while read -r; do
  printf '%s\n' "$REPLY"
  sleep 1
done < infile

sleep 1

while read -u ${COPROC[0]} v; do
  echo "$v"
done

bash-4.1 $ bash s.sh 
one
two
three
four
five

不管怎样,我相信这个测试案例是不恰当的。
你需要一个合作的过程,当你需要一个双向管道(也就是你
需要的聊天的与合作的过程)。您可以使用一个单一的数据库
连接(数据库连接是资源贵)
去来回您的查询和外壳code。

Anyway, I believe that this test case is not appropriate. You need a co-process when you need a two-way pipe (i.e. you need to chat with the co-process). You can use a single database connection (the database connections are resource expensive) and go back and forth with your queries and shell code.

编辑(见下面的评论)。
相关的标准输入的缓冲可以围绕工作的问题
与一些非标刀具(本例中的 stdbuf 的使用(最新版本的一部分的 GNU的coreutils 的,我相信):

Edit (see comments below). The issues related to the stdin buffering could be worked around with some non standard tools (in this case stdbuf is used (part of recent versions of the GNU coreutils, I believe):

~/t$ cat s
coproc stdbuf -oL -i0 mysql

printf '%s;\n' 'show databases' >&${COPROC[1]}

printf '\n\nshowing databases, fisrt time ...\n\n\n'

while read -t3 -u${COPROC[0]}; do
  printf '%s\n' "$REPLY"
  [[ $REPLY == test ]] && {
    printf '%s\n' 'test found, dropping it ...'
    printf '%s;\n' 'drop database test' >&${COPROC[1]}
    }
done

printf '\n\nshowing databases, second time ...\n\n\n'


printf '%s;\n' 'show databases' >&${COPROC[1]}

while read -t3 -u${COPROC[0]}; do
  printf '%s\n' "$REPLY"
done


printf '%s\n' quit >&${COPROC[1]}

输出:

~/t$ bash s


showing databases, fisrt time ...


Database
information_schema
mysql
sakila
test
test found, dropping it ...
world


showing databases, second time ...


Database
information_schema
mysql
sakila
world

我意识到这种方法有很多缺点......

I realize this approach has many drawbacks ...

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

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