【发布时间】:2015-01-27 16:24:13
【问题描述】:
我有一些用于 inotify 的单行生成事件。
while true; do for i in $(seq 1 100); do touch /tmp/ino/foo$i; sleep 1s; done; rm /tmp/ino/foo*; done
然后我设置了一个小型 bash 管道来监视该文件夹,忽略有关 ISDIR 的事件(也许我可以使用 inotifywait 来做到这一点,但这不相关):
inotifywait -m -e close /tmp/ino 2>/dev/null | grep -v ISDIR
效果很好,我看到像/tmp/ino/ CLOSE_WRITE,CLOSE foo57 这样的行。
但如果我在最后添加一个额外的管道,我不会得到任何输出。为简单起见,让我们使用grep pattern 是幂等的事实。
inotifywait -m -e close /tmp/ino 2>/dev/null | grep -v ISDIR | grep -v ISDIR
这会产生 no 输出。我知道我的发电机仍在运行,另一个终端中的无管道inotifywait -m -e close /tmp/ino 仍在产生输出。
经过一番思考,我认为这可能是一个缓冲问题(这样的问题似乎经常出现)。我将管道更改为
inotifywait -m -e close /tmp/ino 2>/dev/null | grep -v ISDIR --line-buffered | grep -v ISDIR
现在我又得到了输出,这样就解决了问题。
但是,我真的不明白为什么它在不强制行缓冲的情况下无法工作。我从来没有遇到过这样的 grep 问题,即使是“生产缓慢”的输出。
但是,管道中的其他一些程序强制 sed 成为 sed -u ,并强制我在每个 awk 语句的末尾添加 fflush() 。
那么,是什么迫使这里出现奇怪的缓冲,我该如何解决(无需在手册页中寻找深奥的强制行缓冲命令)?
【问题讨论】: