Команда Bash tail и несколько труб - PullRequest
4 голосов
/ 15 июня 2019

В настоящее время я сталкиваюсь с проблемой с командой

while sleep 0.3; do echo "1"; done | tail -n +3 | grep --line-buffered "1"

Я хотел вывод, который выглядит следующим образом:

[nothing during 0.6s]
1
1
...

, но имеет:

[nothing forever]

Я нашел этот вопрос и прочитал это сообщение в блоге , но так как опция --line-buffered установлена ​​для grep, я думаю, что это не проблема буферизации.Мои исследования не привели меня к другим решениям, надеюсь, я не упустил что-то очевидное.

Я использую zsh 5.7.1 (x86_64-pc-linux-gnu), если это важно.

Ответы [ 2 ]

4 голосов
/ 15 июня 2019

Как отметил Бармар в комментариях, это поглощается в 4 КБ stdio буфере .Вы можете использовать unbuffer -p, чтобы избежать этого:

while sleep 0.3; do echo "1"; done | unbuffer -p tail -n +3 | grep 1

Или вы также можете использовать stdbuf в режиме буферизации строки:

while sleep 0.3; do echo "1"; done | stdbuf -oL tail -n +3 | grep 1
1 голос
/ 15 июня 2019

В зависимости от реальной ситуации вы можете избежать проблемы (вызванной конвейером от tail до grep), выполнив все с помощью одного более мощного инструмента, такого как awk:

while sleep 0.3; do echo "1"; done | awk 'NR > 2 && /1/'

Но, конечно, если вам нужно перенаправить вывод из awk во что-то еще, у вас просто снова возникнет та же проблема.Но если ваша версия awk поддерживает ее, вы можете явно сбросить вывод:

while sleep 0.3; do echo "1"; done | awk 'NR > 2 && /1/ {print $0; fflush()}' | | while read x; do echo "read '$x'"; done

... или предположительно использовать unbuffer -p или stdbuf -oL на awk (см. Ответ @ JeffBowman),если они у вас есть (у меня их нет, поэтому я не могу их проверить).

...