Для aptitude
-базированного пакета-{backup, restore}, смотрите этот ответ serverfault. Для {deborphan
-based package backup, aptitude
-based package restore}, смотрите совет от Богдана Токовенко (и др.) .
Когда (по крайней мере вывод GNU)grep
не является терминалом, он буферизует свой вывод, что и вызывает поведение, которое вы видите. Вы можете отключить это либо с помощью опции GNU grep
--line-buffered
:
( echo "LINE 1" ; sleep 1 ; echo "LINE 2" ; ) | grep --line-buffered LINE | cat
или утилита stdbuf
:
( echo "LINE 1" ; sleep 1 ; echo "LINE 2" ; ) | stdbuf -oL grep LINE | cat
Отключить буферизацию в канале содержит дополнительную информацию по этой теме.
Используйте
grep --line-buffered
чтобы grep не буферизовал более одной строки за раз.
Как и многие утилиты, это не является чем-то особенным для одной программы, 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
, которые не изменяют внутренностей программы, а просто вставляют псевдо-терминал -в качестве стандартного вывода, так что решение становится "интерактивным", чтобы влиять на это.