Вывод хвостовика трубопровода, хотя grep дважды

В режиме обычного журнала доступа к Apache вы можете запустить:

tail -f access_log | grep "127.0.0.1"

Что будет показывать только журналы (по мере их создания) для указанного IP-адреса.

Но почему это не удается, когда вы нажимаете его, хотя grep во второй раз, чтобы еще больше ограничить результаты?

Например, простое исключение для ".css":

tail -f access_log | grep "127.0.0.1" | grep -v ".css"

не будет выводиться.

Ответы

Ответ 1

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

Попробуйте добавить параметр --line-buffered в свой первый grep:

tail -f access_log | grep --line-buffered "127.0.0.1" | grep -v ".css"

Для получения дополнительной информации см. "BashFAQ/009 - Что такое буферизация? Или почему моя командная строка не производит вывод: tail -f logfile | grep 'foo bar' | awk ..."

Ответ 2

Это результат буферизации, в конечном итоге он будет распечатан, когда будет доступно достаточно данных.

Используйте параметр --line-buffered, предложенный Шон Чин, или если stdbuf доступен, вы можете получить тот же эффект:

tail -f access_log | stdbuf -oL grep "127.0.0.1" | grep -v ".css"