Динамическая передача вывода grep в файл

Мне необходимо из syslog(/var/log/syslog) динамически обновлять, фильтровать и выводить строки с необходимым значением в файл. Грубо говоря делаем tail syslog -f | grep systemd в терминале получаем:

Sep 17 12:57:42 debian systemd[1]: *.service: Succeeded.
Sep 17 12:57:42 debian systemd[1]: Stopped * Web Service.
Sep 17 12:57:42 debian systemd[1]: Starting * Web Service...
Sep 17 12:57:42 debian systemd[1]: Started * Web Service.
Sep 17 12:58:02 debian systemd[1]: Stopping * Web Service...
Sep 17 12:58:02 debian systemd[1]: *.service: Main process exited

И обновляется это все автоматически. Как вывести это в файл?

У меня только идея это: tail syslog -f | grep systemd > echo >> /root/systemd.log Но в файл ничего не передается от слова совсем (Или задержка передачи какая-то огромная. Как можно динамически близко к реал-тайму передавать данные в файл?


Ответы (1 шт):

Автор решения: aleksandr barakin

программа grep (если stdin остаётся открытым, а stdoutне терминал) для повышения производительно буферизует выводимую информацию. пока не заполнился буфер вывода, она ничего не выводит.

чтобы программа не ожидала заполнения буфера, а отправляла информацию по-строчно, можно использовать опцию --line-buffered.


пример. вот так выводит (и остаётся работать):

$ echo x > файл
$ tail -f файл | grep x
x

а тут (для простоты взята запись в «трубу» (pipe), а не файл) не выводит ничего потому, что у первого из процессов grep вывод осуществляется не в терминал:

$ tail -f файл | grep x | grep x

добавляем опцию --line-buffered — вывод идёт по-строчно:

$ tail -f файл | grep --line-buffered x | grep x
x

другой вариант: запускать процесс grep, «обёрнутый» вызовом stdbuf (с опцией -o0, означающей отключение буферизации):

$ tail -f файл | stdbuf -o0 grep x | grep x
x
→ Ссылка