Polecenia na ogół nie buforują danych wejściowych. Zrobiliby to read()
dla dużej porcji, ale jeśli czytając z potoku, nie ma tak wielu bajtów w potoku, read()
wywołanie systemowe powróci z tyloma znakami, a aplikacja na ogół będzie z tym pracować, jeśli może .
Godnym uwagi wyjątkiem jest to, mawk
które będzie się utrzymywało read()
do momentu zapełnienia bufora wejściowego.
Aplikacje buforują jednak dane wyjściowe (standardowe wyjście). Zwykle zachowuje się tak, że jeśli dane wyjściowe zmienią się na tty, wówczas buforowanie będzie przebiegać liniowo (to znaczy, że nie zacznie zapisywać do standardowego wyjścia, dopóki nie będzie miał pełnej linii do wyjścia lub pełnego bloku dla bardzo długa linia), podczas gdy dla każdego innego typu pliku buforowanie odbywa się według bloków (to znaczy, że nie zacznie pisać, dopóki nie zostanie zapełniony jeden blok (coś takiego jak 4KiB / 8KiB ... zależy od oprogramowania i systemu) )).
Więc w twoim przypadku LongRunningCommand
prawdopodobnie buforuje swoje wyjście blokami (ponieważ jego wyjściem jest potok, a nie tty), i tr
prawdopodobnie buforuje jego wyjście według linii, ponieważ prawdopodobnie jest to terminal.
Ponieważ jednak usuniesz każdy znak nowej linii z jego wyniku, nigdy nie wypisze on wiersza, więc buforowanie będzie odbywało się według bloku.
Więc tutaj chcesz wyłączyć buforowanie dla obu LongRunningCommand
i tr
. W systemach GNU lub FreeBSD:
stdbuf -o0 LongRunningCommand | stdbuf -o0 tr '\n' ,
Pamiętaj, że jeśli chcesz połączyć linie przecinkiem, lepszym rozwiązaniem jest użycie paste -sd , -
. W ten sposób wyjście zostanie zakończone znakiem nowej linii (prawdopodobnie nadal będziesz musiał wyłączyć buforowanie).
stdbuf
do LongRunningCommand lub do tr, czy do obu, inaczej?