У меня есть однострочные события генерации для inotify.inotify + stdout piping - выход теряется в трубе
while true; do for i in $(seq 1 100); do touch /tmp/ino/foo$i; sleep 1s; done; rm /tmp/ino/foo*; done
Затем я создал небольшую оргию трубопровод, чтобы посмотреть эту папку, игнорируя события о 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
Это производит не выхода. Я знаю, что мой генератор все еще работает, а бесконтактный 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
, и вынуждая меня добавить fflush()
в конце каждого awk
.
Итак, что заставляет странную буферизацию здесь, и как я могу ее исправить (без необходимости царапать в man-страницах, ищущих команды эзотерической силовой линии)?
Большинство команд не имеют таких проблем. Неужели это 'inotifywait' не может быть правильно' unix'y или что-то еще? – Squidly
«Большинство команд»? Сомневаюсь. Например, в документации Perl говорится: «STDOUT, как правило, буферизуется в строке, если вывод выполняется на терминал, а блок буферизуется в противном случае». Это демонстрируется как различия между «perl -E» say «one»; сон 3; скажем, «два» и «perl -E» говорят «один»; сон 3; сказать «два» | cat' и 'perl -E '$ | = 1; скажем «один»; сон 3; сказать «два» | cat' –