Спрощене пояснення
Як і багато комунальних служб, ця функція не є чимось властивим одній програмі, і grep
змінює її стандартний вихід між буферизованою лінією та повністю завантаженою . У першому випадку бібліотека C буферизує вихідні дані в пам'яті до тих пір, поки не заповниться або буфер, що містить ці дані, або до нього додається символ передачі рядків (або програма закінчується чисто), після чого він закликає write()
фактично записати вміст буфера. В останньому випадку запускається тільки буфер в пам'яті, який заповнюється (або програма закінчується чисто) write()
.
Більш детальне пояснення
Це відоме, але трохи неправильне пояснення. Насправді, стандартний вихід не буферизований у рядку, а розумний буфер у бібліотеці GNU C та BSD C. Стандартний вихід також видається, коли при зчитуванні стандартного входу вичерпується його буфер пам'яті (попереднього введення), і бібліотека C повинна викликати read()
ще один вхід, і він читає початок нового рядка. (Однією з причин цього є запобігання тупикової ситуації, коли інша програма підключається до обох кінців фільтра і очікує, що зможе працювати по черзі, чергуючи запис у фільтр і зчитування з нього; наприклад, "копроцеси" в GNU awk
наприклад.)
C вплив бібліотеки
grep
а інші утиліти роблять це - або, більш строго, бібліотеки C, якими вони користуються, роблять це, оскільки це визначена особливість програмування мовою С - на основі того, що вони визначають, що їх стандартний вихід. Якщо (і лише якщо) це не інтерактивний пристрій, вони обирають повну буферизацію, інакше вони вибирають розумну буферизацію. Труба вважається не інтерактивним пристроєм, оскільки визначення як інтерактивного пристрою, принаймні у світі Unix та Linux, по суті є isatty()
викликом, що повертає істину для відповідного дескриптора файлів.
Обхідні шляхи відключення повного буферизації
Деякі утиліти, як-от, grep
мають ідіосинкратичні варіанти, наприклад, --line-buffered
що змінюють це рішення, яке, як ви бачите, неправильно названо. Але така фігура програм, які можна було використати, зникає на малі.
Більш загально, можна використовувати інструменти, які копаються у специфічній бібліотеці С та змінюють її прийняття рішень (які мають проблеми із безпекою, якщо програма, яку потрібно змінити, встановлена UID, а також є специфічною для конкретних бібліотек С, і справді є специфічні для програм, написаних або розшарованих на мові С), або таких інструментів, ptybandage
які не змінюють внутрішні програми програми, а просто вставляють псевдотермінал як стандартний вихід, щоб рішення виходило як "інтерактивне", щоб впливати на це.
Подальше читання
cat
об'єднує файли. Що ви намагаєтесь зробити, використовуючи трубиcat
?