grep и sed с pipe из tail -f, похоже, кэшируют

grep и sed с pipe из tail -f, похоже, кэшируют

Я пытаюсь получить работающую систему для мониторинга специальных журналов. Обычно мне просто нужен очень конкретный шаблон, который я извлекаю с помощью grepи канала из tail -f. Я заметил, что grep не выводит все, а вместо этого сохраняет некоторые строки в буфере. Думаю, это имеет смысл, если у вас есть канал, который выводит все, а затем завершает и закрывает поток.
Но с tail -fэтим у меня не получается.

Та же проблема возникает и с sed.

Вот пример команды, которую я хочу использовать:

clear && tail -F -n1000 /var/log/fail2ban.log | grep 'WARNING.*Ban' | sed s/'fail2ban.actions: WARNING '//g | grep -E --color 'ssh-iptables-perma|$'

Приведем пример:

Последняя строка приведенной выше команды выглядит так:

2015-05-04 11:17:24,551 [ssh-iptables] Ban x.x.x.x

И с помощью этой команды:

clear && tail -F -n1000 /var/log/fail2ban.log | grep 'WARNING.*Ban' | sed s/'fail2ban.actions: WARNING '//g

Последняя строка такая:

2015-05-04 19:45:17,615 [ssh-iptables] Ban y.y.y.y

Удаление дополнительных трубок позволяет перейти к самым последним записям.

Как можно избежать этого кэширования в трубах?

решение1

Добавить grepопцию --line-bufferedи sedопцию --unbuffered.

решение2

Используйте grepопцию --line-buffered.

По умолчанию утилиты используют буферизацию строк, если их стандартный вывод представляет собой терминал, но используют буферы большего размера (вероятно, 4 или 8 КБ), когда их вывод подключен к файловому дескриптору или каналу.

Вам повезло, что tail -Fвы используете буферизацию строк по умолчанию и grepимеете параметр командной строки для ее включения. Я не знаю универсального метода включения буферизации строк для произвольной команды.

Связанный контент