I comandi generalmente non bufferizzano il loro input. Farebbero un read()
per un grosso pezzo, ma quando leggono da una pipe, se non ci sono tanti byte nella pipe, la read()
chiamata di sistema restituirà con quanti più caratteri ci sono e l'applicazione generalmente funzionerà con quella se può .
Un'eccezione notevole a ciò è mawk
che rimarrà attiva read()
fino a quando il buffer di input non sarà pieno.
Le applicazioni bufferizzano il loro output (stdout) però. Il comportamento normale è che se l'output sta per raggiungere un valore tty, il buffering sarà a livello di linea (ovvero, non inizierà a scrivere su stdout fino a quando non avrà una riga intera da emettere, o un blocco pieno per molto linea lunga), mentre per ogni altro tipo di file, il buffering è per blocchi (cioè, non inizierà a scrivere finché non ha un blocco pieno da scrivere (qualcosa come 4KiB / 8KiB ... dipende dal software e dal sistema )).
Quindi nel tuo caso LongRunningCommand
probabilmente buffer il suo output per blocchi (dal momento che il suo output è una pipe e non una tty), e tr
probabilmente buffer il suo output per linea poiché il suo output è probabilmente il terminale.
Ma, poiché rimuovi ogni carattere di nuova riga dal suo output, non genererà mai una riga, quindi il buffering sarà a blocchi.
Quindi qui vuoi disabilitare il buffering per entrambi LongRunningCommand
e tr
. Sui sistemi GNU o FreeBSD:
stdbuf -o0 LongRunningCommand | stdbuf -o0 tr '\n' ,
Si noti che se si desidera unire le linee con una virgola, è necessario utilizzare un approccio migliore paste -sd , -
. In questo modo l'output verrà terminato da un carattere di nuova riga (probabilmente dovrai comunque disabilitare il buffering).
stdbuf
a LongRunningCommand o a tr, o ad entrambi, in modo diverso?