Динамическая передача вывода 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 шт):
программа 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