Как использовать 'grep' для непрерывного потока?
Возможно ли использовать grep на непрерывном потоке данных?
Я имею в виду что-то вроде команды tail -f <file>, но с применением grep к этому выводу, чтобы оставить только интересующие меня строки.
Я пробовал команду tail -f <file> | grep pattern, но, кажется, grep может выполняться только после завершения работы tail, то есть никогда.
5 ответ(ов)
Чтобы включить режим построчной буферизации в grep на BSD (таких как FreeBSD, Mac OS X и др.), вы можете использовать следующую команду:
tail -f file | grep --line-buffered my_pattern
Ранее для GNU grep (который используется практически на всех дистрибутивах Linux) параметр --line-buffered, как правило, не имел значения, так как по умолчанию происходило принудительное сбрасывание буфера. Однако с ноября 2020 года этот параметр стал необходимым (как минимум, для GNU grep 3.5 на openSUSE) и, судя по комментариям, это также верно и для других систем.
Обратите внимание, что поведение может отличаться в зависимости от конкретного дистрибутива и версии grep, поэтому если вы работаете в среде, отличной от Linux, возможно, стоит проверять документацию для вашей ОС, чтобы всегда быть в курсе изменений и возможностей инструмента.
Вы можете использовать команду tail -f <file> | grep --line-buffered <pattern>, чтобы избежать проблемы с буферизацией. По умолчанию grep вызывает буферизацию вывода, что может привести к задержкам в отображении результатов. Используя параметр --line-buffered, вы можете получить результаты сразу же по мере их появления, а не дожидаться завершения вывода. Сначала выполните команду:
tail -f <file> | grep --line-buffered <pattern>
Это должно решить вашу проблему, и вы получите вывод в реальном времени без задержек.
Если вам нужно находить совпадения во всем файле (а не только в его конце) и ожидать появления новых совпадений, вы можете использовать следующую команду:
tail -c +0 -f <file> | grep --line-buffered <pattern>
Флаг -c +0 указывает, что вывод должен начинаться с 0 байт (-c) от начала файла (+).
Я думаю, что ваша проблема связана с тем, что grep использует буферизацию вывода. Попробуйте использовать следующую команду:
tail -f file | stdbuf -o0 grep my_pattern
Это установит режим буферизации вывода для grep на неблокирующий.
В большинстве случаев вы можете использовать команду tail -f /var/log/some.log | grep foo, и это будет работать нормально.
Если вам нужно использовать несколько grep на работающем файлe журнала и вы обнаружили, что не получаете вывода, то вам может потребоваться добавить ключ --line-buffered в средний grep, вот так:
tail -f /var/log/some.log | grep --line-buffered foo | grep bar
Прерывание скрипта оболочки при возвращении любой команды ненулевого значения
Как убить процесс по имени вместо PID в Linux?
Как передавать параметры в Bash-скрипт?
Shell Script: Чтение ввода на той же строке после вывода сообщения
Как добавить строку текста в середину файла с помощью bash?