Как использовать '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
Как запросить ввод Yes/No/Cancel в скрипте оболочки Linux?
Определение переменной с экспортом или без него
Как изменить цвет вывода echo в Linux
Как сделать паузу в shell-скрипте на одну секунду перед продолжением?
Как работает "cat << EOF" в bash?