2015-01-27 2 views
1

У меня есть однострочные события генерации для 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-страницах, ищущих команды эзотерической силовой линии)?

ответ

1

inotifywait, вероятно, буферизуется. Я бы предложил использовать stdbuf:

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

Большинство команд не имеют таких проблем. Неужели это 'inotifywait' не может быть правильно' unix'y или что-то еще? – Squidly

+0

«Большинство команд»? Сомневаюсь. Например, в документации Perl говорится: «STDOUT, как правило, буферизуется в строке, если вывод выполняется на терминал, а блок буферизуется в противном случае». Это демонстрируется как различия между «perl -E» say «one»; сон 3; скажем, «два» и «perl -E» говорят «один»; сон 3; сказать «два» | cat' и 'perl -E '$ | = 1; скажем «один»; сон 3; сказать «два» | cat' –

Смежные вопросы