【问题标题】:inotify + stdout piping - output being lost in a pipeinotify + stdout 管道 - 输出在管道中丢失
【发布时间】: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()

那么,是什么迫使这里出现奇怪的缓冲,我该如何解决(无需在手册页中寻找深奥的强制行缓冲命令)?

【问题讨论】:

    标签: linux shell buffering


    【解决方案1】:

    inotifywait 可能正在缓冲。我会建议使用stdbuf:

    stdbuf -oL inotifywait -m -e close /tmp/ino 2>/dev/null | grep ...
    

    【讨论】:

    • 大多数命令没有这样的问题。这是inotifywait 不是正确的unixy 还是别的什么?
    • “大多数命令”?对此感到怀疑。例如,perl 的文档说:“如果输出到终端,STDOUT 通常会被行缓冲,否则会被块缓冲。”,这被证明为 perl -E 'say "one"; sleep 3; say "two"'perl -E 'say "one"; sleep 3; say "two"' | catperl -E '$|=1; say "one"; sleep 3; say "two"' | cat 之间的差异
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多