Упрощенное объяснение
Подобно многим утилитам, это не является чем-то особенным для одной программы, и grep
ее стандартный вывод варьируется от линейной буферизации до полной буферизации . В первом случае библиотека C буферизует выходные данные в памяти до тех пор, пока либо буфер, содержащий эти данные, не будет заполнен, либо к нему не будет добавлен символ перевода строки (или программа завершится корректно), после чего она вызывает write()
фактическую запись содержимого буфера. В последнем случае только заполнение буфера в памяти (или корректное завершение программы) вызывает write()
.
Более подробное объяснение
Это хорошо известное, но слегка ошибочное объяснение. Фактически, стандартный вывод не буферизован строкой, а умным буферизован в библиотеке GNU C и библиотеке BSD C. Стандартный вывод также сбрасывается, когда при чтении стандартного ввода исчерпывается его буфер в памяти (для ввода с предварительным чтением), и библиотека C должна вызывать, read()
чтобы получить еще какой-то ввод, и она читает начало новой строки. (Одной из причин этого является предотвращение взаимоблокировки, когда другая программа подключается к обоим концам фильтра и ожидает, что сможет работать построчно, чередуя запись в фильтр и чтение из него; например, «сопроцессы» в GNU awk
например.)
Влияние библиотеки C
grep
и другие утилиты делают это - или, точнее, библиотеки C, которые они используют, делают это, потому что это определенная особенность программирования на языке C - на основе того, что они обнаруживают в своем стандартном выводе. Если (и только если) это не интерактивное устройство, они выбирают полную буферизацию, в противном случае они выбирают интеллектуальную буферизацию. Канал считается не интерактивным устройством, потому что определение интерактивного устройства, по крайней мере в мире Unix и Linux, по сути является isatty()
вызовом, возвращающим true для соответствующего файлового дескриптора.
Обходные пути для отключения полной буферизации
Некоторые утилиты, такие как, grep
имеют специфические опции, например, --line-buffered
которые изменяют это решение, которое, как вы можете видеть, имеет неправильное название. Но на самом деле очень малая часть программ-фильтров, которые можно было бы использовать, на самом деле имеет такую возможность.
В более общем смысле, можно использовать инструменты, которые копаются во внутренних структурах библиотеки C и изменяют ее принятие решений (которые имеют проблемы с безопасностью, если программа, для которой нужно изменить, имеет установленный UID, а также специфичны для конкретных библиотек C и действительно являются специфичные для программ, написанных на языке C или наложенных поверх него), или такие инструменты, ptybandage
которые не изменяют внутреннюю часть программы, а просто вставляют псевдотерминал в качестве стандартного вывода, так что решение выходит «интерактивным», чтобы повлиять на это.
дальнейшее чтение
cat
объединяет файлы. Что вы пытаетесь сделать, проникая вcat
?