为什么我不能通过管道多次过滤tail的输出?
Why can't I filter tail's output multiple times through pipes?
出乎意料,这失败了(无输出;在sh、zsh、bash):
echo "foo\nplayed\nbar" > /tmp/t && tail -f /tmp/t | grep played | sed 's#pl#st#g'
请注意,两次 grep 也失败了,表明使用了哪些命令完全无关紧要:
# echo -e "foo\nplayed\nbar" > /tmp/t && tail -f /tmp/t | grep played | grep played
grep 单独工作:
# echo -e "foo\nplayed\nbar" > /tmp/t && tail -f /tmp/t | grep played
played
sed 单独工作:
# echo -e "foo\nplayed\nbar" > /tmp/t && tail -f /tmp/t | sed 's#pl#st#g'`
foo
stayed
bar
使用 cat 而不是 tail,它有效:
# echo -e "foo\nplayed\nbar" > /tmp/t && cat /tmp/t | grep played | sed 's#pl#st#g'
stayed
使用 journalctl --follow
,它会像使用 tail
一样失败。
两次无法管道是什么原因?
这是一个缓冲问题 - 第一个 grep 在管道传输到另一个命令时缓冲它的输出,但在打印到 stdout 时则不然。有关更多信息,请参阅 http://mywiki.wooledge.org/BashFAQ/009。
出乎意料,这失败了(无输出;在sh、zsh、bash):
echo "foo\nplayed\nbar" > /tmp/t && tail -f /tmp/t | grep played | sed 's#pl#st#g'
请注意,两次 grep 也失败了,表明使用了哪些命令完全无关紧要:
# echo -e "foo\nplayed\nbar" > /tmp/t && tail -f /tmp/t | grep played | grep played
grep 单独工作:
# echo -e "foo\nplayed\nbar" > /tmp/t && tail -f /tmp/t | grep played
played
sed 单独工作:
# echo -e "foo\nplayed\nbar" > /tmp/t && tail -f /tmp/t | sed 's#pl#st#g'`
foo
stayed
bar
使用 cat 而不是 tail,它有效:
# echo -e "foo\nplayed\nbar" > /tmp/t && cat /tmp/t | grep played | sed 's#pl#st#g'
stayed
使用 journalctl --follow
,它会像使用 tail
一样失败。
两次无法管道是什么原因?
这是一个缓冲问题 - 第一个 grep 在管道传输到另一个命令时缓冲它的输出,但在打印到 stdout 时则不然。有关更多信息,请参阅 http://mywiki.wooledge.org/BashFAQ/009。