tr
wydaje się buforować dane wejściowe, dzięki czemu to polecenie LongRunningCommand|tr \\n ,
zacznie generować dane wyjściowe dopiero po zgromadzeniu kilku kilobajtów danych wejściowych z LongRunningCommand.
Czy istnieje sposób na wymuszenie tr
zatrzymania buforowania lub innego polecenia, które może zastąpić nowe wiersze innym znakiem bez buforowania?
PS Próbowałem już dwóch pierwszych sugestii z Wyłącz buforowanie w potoku bez powodzenia.
stdbuf
do LongRunningCommand lub do tr, czy do obu, inaczej?stdbuf -o0 fping -aAq -r2 -g 10.30.0.1 10.30.0.255 2>/dev/null | stdbuf -i0 tr \\n ,
fping -q
mówi „Nie pokazuj wyników dla pojedynczej sondy, ale tylko końcowe podsumowanie”, więc może to tylko jeden długi napis na końcu?tr
. Spróbuj|stdbuf -i0 -o0 tr ...
Odpowiedzi:
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łoread()
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), itr
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
itr
. W systemach GNU lub FreeBSD: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).źródło
sed
. przepraszam, jeśli to było denerwujące - ale nie zdawałem sobie sprawy, że to wiedza ogólna. Myślę, że używa LD_PRELOAD.Aby zastąpić znaki nowej linii
","
, możesz uruchomićGNU awk (
gawk
) i Solarisnawk
będą działać z buforowaniem linii na stdin i bez buforowania stdout, gdy wyjście jest na terminalu. Jeśli masz awkmawk
, co dzieje się na Ubuntu, możesz dać mu-W interactive
opcję uzyskania takiego samego zachowania buforowania.źródło