我正在尝试使用bash coproc
,但遇到了困难,很可能是缓冲。我有一个复杂的命令,它接受来自标准输入的面向行的输入,并在每行输入中打印一行到标准输出。在命令行中,此命令在每行基础上都可以正常工作,但是当我将其放入 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
and之间进行管道连接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
在交互模式下将对其标准输出进行行缓冲,否则它将使用更大的缓冲区。