Как и многие утилиты, это не является чем-то особенным для одной программы, grep
варьирует свой стандартный вывод между строковой буферизацией и полной буферизацией . В первом случае библиотека C буферизует выходные данные в памяти до тех пор, пока либо буфер, содержащий эти данные, не будет заполнен, либо к нему не будет добавлен символ перевода строки (, либо программа не завершится чисто ), после чего она вызывает write()
для фактического записать содержимое буфера. В последнем случае только переполнение буфера памяти in -(или чистое завершение программы )вызывает write()
.
Это хорошо -известное, но несколько неверное объяснение. На самом деле стандартный вывод не буферизуется строкой, а буферизуется умно в библиотеке GNU C и библиотеке C BSD.Стандартный вывод также сбрасывается при чтении стандартного ввода исчерпывает его в -буфере памяти (предварительного -чтения ввода )и Библиотека C должна вызвать read()
, чтобы получить дополнительные входные данные и , она читает начало новой строки. (Одной из причин этого является предотвращение взаимоблокировки, когда другая программа подключается к обоим концам фильтра и ожидает, что сможет работать со строкой -за строкой -, чередуя запись в фильтр и чтение из него; как, например, «сопроцессы» в GNU awk
.)
grep
и другие утилиты делают это — или, точнее, библиотеки C, которые они используют, делают это, потому что это определенная особенность программирования на языке C — на основе того, что они определяют как их стандартный вывод. Если (и только если )это не интерактивное устройство, они выбирают полную буферизацию, в противном случае выбирают умную буферизацию. Канал считается не интерактивным устройством, потому что определение интерактивного устройства, по крайней мере, в мире Unix и Linux, по сути, является вызовом isatty()
, возвращающим true для соответствующего файлового дескриптора.
Некоторые утилиты, такие как grep
, имеют уникальные параметры, такие как --line-buffered
, которые изменяют это решение, которое, как вы видите, имеет неправильное -название. Но исчезающе малая доля программ-фильтров, которые можно было бы использовать, на самом деле имеют такую возможность.
В более общем смысле можно использовать инструменты, которые копаются во внутренностях библиотеки C и изменяют процесс принятия решений, (которые имеют проблемы с безопасностью, если для изменяемой программы установлен -UID, а также специфичны для конкретных библиотек C и действительно относятся к программам, написанным на языке C или наложенным на него ),или такие инструменты, как ptybandage
, которые не изменяют внутренностей программы, а просто вставляют псевдо-терминал -в качестве стандартного вывода, так что решение становится "интерактивным", чтобы влиять на это.
Вы поняли почти правильно:
tail -f /var/www/access.log | logresolve
должно работать на вас. (logresolve, по крайней мере, насколько я мог понять из справочной страницы , читает из «стандартного ввода» и выводит в «стандартный вывод», поэтому приведенное выше просто передает в него access.log.