Команди, як правило, не буферують свій вхід. Вони зробили б read()
великий фрагмент, але якщо читати з труби, якщо в трубі не так багато байтів, read()
системний виклик повернеться з такою кількістю символів, і програма, як правило, працює з цим, якщо зможе .
Помітним винятком є те, mawk
що буде тривати read()
до тих пір, поки вхідний буфер не заповниться.
Хоча програми буферують свій вихід (stdout). Звичайна поведінка полягає в тому, що якщо вихід збирається в tty, то буферизація буде лінійною (тобто вона не почне писати до stdout, поки у неї не буде повна лінія для виведення, або блок-full для дуже довгий рядок), а для кожного іншого типу файлів буферизація здійснюється блоками (тобто він не почне писати, доки не буде заповнений один блок для запису (щось на зразок 4KiB / 8KiB ... залежить від програмного забезпечення та системи )).
Тож у вашому випадку LongRunningCommand
ймовірно буферизує його вихід блоками (оскільки його вихід - це труба, а не tty), і, tr
ймовірно, буферизує його вихід за рядком, оскільки його вихід, ймовірно, є терміналом.
Але, оскільки ви видаляєте кожен символ нового рядка зі свого виводу, він ніколи не виводить лінію, тому буферизація буде здійснюватися блоком.
Отже, тут ви хочете відключити буферизацію і для, LongRunningCommand
і для tr
. У системах GNU або FreeBSD:
stdbuf -o0 LongRunningCommand | stdbuf -o0 tr '\n' ,
Зауважте, що якщо ви хочете з'єднати рядки комою, кращим підходом є використання paste -sd , -
. Таким чином вихід буде припинено символом нового рядка (вам, ймовірно, все одно потрібно буде відключити буферизацію).
stdbuf
до LongRunningCommand або до tr, або до обох, по-різному?