通过grep拖尾时无输出 [英] No output while piping tail through grep
问题描述
位于$filepath
的文件逐渐增加.我想打印以感叹号开头的每一行:
There is a file located at $filepath
, which grows gradually. I want to print every line that starts with an exclamation mark:
while read -r line; do
if [ -n "$(grep ^! <<< "$line")" ]; then
echo "$line"
fi
done < <(tail -F -n +1 "$filepath")
然后,我通过将比较表达式移到流程替换中来重新排列代码,以使代码更简洁:
Then, I rearranged the code by moving the comparison expression into the process substitution to make the code more concise:
while read -r line; do
echo "$line"
done < <(tail -F -n +1 "$filepath" | grep '^!')
可悲的是,它无法按预期运行;什么都不会打印到终端(stdout).
Sadly, it doesn't work as expected; nothing is printed to the terminal (stdout).
我更喜欢在tail
之后写grep ^\!
.为什么第二个代码段不起作用?为什么将命令管道放入流程替换中会使事情有所不同?
I prefer to write grep ^\!
after tail
. Why doesn't the second code snippet work? Why putting the command pipe into the process substitution make things different?
PS1.这就是我通过随机执行以下命令之一来手动生成逐渐增长的文件的方式:
PS1. This is how I manually produce the gradually growing file by randomly executing one of the following commands:
echo ' something' >> "$filepath"
echo '!something' >> "$filepath"
PS2.在GNU bash, version 4.3.48(1)-release
和tail (GNU coreutils) 8.25
下进行测试.
PS2. Test under GNU bash, version 4.3.48(1)-release
and tail (GNU coreutils) 8.25
.
推荐答案
grep
在其stdout未连接到tty时没有行缓冲.因此,它试图在生成一些输出之前处理一个块(通常为4 KiB或8 KiB左右).
grep
is not line-buffered when its stdout isn't connected to a tty. So it's trying to process a block (usually 4 KiB or 8 KiB or so) before generating some output.
您需要告诉grep
按行缓冲其输出.如果您使用的是GNU grep,则可以:
You need to tell grep
to buffer its output by line. If you're using GNU grep, this works:
done < <(tail -F -n +1 "$filepath" | grep '^!' --line-buffered)
^^^^^^^^^^^^^^^
这篇关于通过grep拖尾时无输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!