我正在尝试使用bash coproc
而我遇到了困难,最有可能是缓冲。我有一个复杂的命令,它接受来自stdin的面向行的输入,并在每行输入中打印一行到stdout。在命令行中,此命令在每行的基础上正常工作,但是当我将它放在一个coproc中并从${COPROC[0]}
FD读取时,读取块。
我可以使用paste
重新创建此行为,但不能使用cat
重新创建此行为。我希望paste
和cat
在传递任何参数时几乎都做同样的事情。直接在命令提示符下运行时就是这种情况:
$ cat
Hello World!<RETURN>
Hello World!^D
$ paste
Hello World!<RETURN>
Hello World!^D
$
(RETURN
和^D
已添加以供说明)
但是,当我将它们放在coproc中时,它们的行为有所不同 - cat
严格地是行缓冲的,而paste
似乎使用更大的缓冲区运行:
$ coproc cat
$ echo 'Hello world!' >&${COPROC[1]}
$ read -ru ${COPROC[0]} line; echo $line
Hello world!
$ kill $COPROC_PID
[3]+ Terminated coproc COPROC cat
$
$ coproc paste
[3] 42657
$ echo 'Hello world!' >&${COPROC[1]}
$ read -ru ${COPROC[0]} line; echo $line
#### read blocks here until ^C ####
我认为原因是paste
根据连接的内容调整缓冲模式,而cat
始终处于行缓冲模式。
有没有办法强制paste
(或其他常规命令)在coproc中进行行缓冲?
经过一些实验后,我发现我可以在没有coproc的情况下重新创建类似的行为,而只是在cat
和paste
之间滚动:
$ cat | cat
Hello World!<RETURN>
Hello World!^D
$ cat | paste
Hello World!<RETURN>
Hello World!^D
$ paste | cat
Hello World!<RETURN>
#### command blocks here until ^C ####
(RETURN
和^D
已添加以供说明)
cat
传递给cat
,然后一路缓冲cat
传递给paste
并尽可能地获得行缓冲paste
传递给cat
并且没有获得行缓冲这似乎表明paste
将在交互模式下对其标准输出进行缓冲,但否则会使用更大的缓冲区。
答案 0 :(得分:0)
强制行缓冲的一种方法是使用stdbuf
coreutils工具(如果有):
stdbuf
允许用户修改与程序相关的三个标准I / O流的缓冲操作。
对于coproc
案例:
$ coproc stdbuf -oL paste
[3] 42751
$ echo 'Hello world!' >&${COPROC[1]}
$ read -ru ${COPROC[0]} line; echo $line
Hello world!
$ kill $COPROC_PID
[3]+ Terminated coproc COPROC stdbuf -oL paste
$
对于paste
到cat
案例的简单管道:
$ stdbuf -oL paste | cat
Hello World!<RETURN>
Hello World!^D
$