Istnieje ogólna reguła buforowania, po której następuje standardowa biblioteka C we / wy ( stdio) używana przez większość programów uniksowych. Jeśli wyjście trafia do terminala, jest opróżniane na końcu każdej linii; w przeciwnym razie jest opróżniany tylko wtedy, gdy bufor (8 KB na moim systemie Linux / amd64; może być inny na twoim) jest pełny.
Jeśli wszystkie media były zgodnie z ogólną regułę, że widzisz wyjścia z opóźnieniem wszystkich przykładów ( cat|sed, cat|tr, i cat|tr|sed). Ale jest wyjątek: GNU catnigdy nie buforuje swoich danych wyjściowych. Nie używa stdiolub zmienia domyślną stdiozasadę buforowania.
Mogę być całkiem pewien, że używasz GNU, cata nie jakiegoś innego Uniksa, catponieważ inni nie zachowaliby się w ten sposób. Tradycyjny unix catma -uopcję żądania niebuforowanych danych wyjściowych. GNU catignoruje tę -uopcję, ponieważ jej dane wyjściowe są zawsze niebuforowane.
Tak więc, gdy masz rurkę z catlewym, w systemie GNU, przepływ danych przez rurę nie będzie opóźniony. catNawet nie będzie wiersz po wierszu - terminal robi to. Podczas wpisywania danych wejściowych dla cat, twój terminal jest w trybie „kanonicznym” - oparty na linii, z klawiszami edycji takimi jak backspace i ctrl-U, oferującymi możliwość edycji linii, którą wpisałeś przed wysłaniem Enter.
W tym cat|tr|sedprzykładzie trnadal odbiera dane, catgdy tylko naciśniesz Enter, ale trpostępuje zgodnie z stdiodomyślną zasadą: jego wyjście przechodzi do potoku, więc nie opróżnia się po każdej linii. Zapisuje do drugiego potoku, gdy bufor jest pełny lub po otrzymaniu EOF, w zależności od tego, co nastąpi wcześniej.
sedpostępuje również zgodnie z stdiodomyślną polityką, ale jego dane wyjściowe trafiają do terminala, więc zapisze każdą linię, gdy tylko się z nią skończy. Wpływa to na to, ile musisz wpisać, zanim coś pojawi się na drugim końcu potoku - jeśli sedbuforowanie blokowe jego danych wyjściowych, musisz wpisać dwa razy więcej (aby wypełnić trbufor wyjściowy i sed dane wyjściowe bufor).
GNU sedma -uopcję, więc jeśli odwrócisz kolejność i cat|sed -u|trużyjesz, zobaczysz, że dane wyjściowe pojawią się ponownie. (Ta sed -uopcja może być dostępna gdzie indziej, ale nie sądzę, że jest to starożytna tradycja uniksowa taka jak cat -u). O ile wiem, nie ma równoważnej opcji tr.
Istnieje narzędzie o nazwie, stdbufktóre pozwala zmienić tryb buforowania każdego polecenia, które korzysta z stdiowartości domyślnych. Jest to trochę kruche, ponieważ wykorzystuje się LD_PRELOADdo osiągnięcia czegoś, co biblioteka C nie została zaprojektowana do obsługi, ale w tym przypadku wydaje się działać:
cat | stdbuf -o 0 tr '[:lower:]' '[:upper:]' | sed 'p'
catbuforuje się aż do zamknięcia standardowego wejścia.