重击尾巴命令和多个管道

时间:2019-06-14 22:06:04

标签: bash pipe

我当前遇到命令问题

while sleep 0.3; do echo "1"; done | tail -n +3 | grep --line-buffered "1"

我想要的输出如下:

[nothing during 0.6s]
1
1
...

但有:

[nothing forever]

我找到了this question并阅读了this blog post,但是由于--line-buffered设置了grep选项,因此我认为这不是一个缓冲问题。我的研究并未将我引向其他解决方案,我希望我不要错过任何显而易见的事情。

如果重要,我正在使用zsh 5.7.1 (x86_64-pc-linux-gnu)

2 个答案:

答案 0 :(得分:4)

正如Barmar在评论中所提到的,它被4KB stdio buffer吞没了。您可以使用unbuffer -p来避免它:

while sleep 0.3; do echo "1"; done | unbuffer -p tail -n +3 | grep 1

或者您也可以在行缓冲模式下使用stdbuf

while sleep 0.3; do echo "1"; done | stdbuf -oL tail -n +3 | grep 1

答案 1 :(得分:1)

根据实际情况,您可以通过使用一个更强大的工具(如{{1})来完成所有操作(由tailgrep的管道引起) }:

awk

但是,当然,如果您需要将while sleep 0.3; do echo "1"; done | awk 'NR > 2 && /1/' 的输出传递给其他内容,那么您将再次遇到相同的问题。但是,如果您的awk版本支持该功能,则可以显式刷新输出:

awk

......或者大概在while sleep 0.3; do echo "1"; done | awk 'NR > 2 && /1/ {print $0; fflush()}' | | while read x; do echo "read '$x'"; done 上使用unbuffer -pstdbuf -oL(请参阅@JeffBowman的答案),如果有的话(我没有,所以我无法对其进行测试)。