Esiste una regola di buffering generale seguita dalla libreria I / O standard C ( stdio) utilizzata dalla maggior parte dei programmi unix. Se l'uscita sta per un terminale, viene scaricata alla fine di ogni riga; altrimenti viene scaricato solo quando il buffer (8K sul mio sistema Linux / amd64; potrebbe essere diverso sul tuo) è pieno.
Se tutte le utilità seguivano la regola generale, si dovrebbe vedere l'uscita in ritardo in tutti i tuoi esempi ( cat|sed, cat|tr, e cat|tr|sed). Ma c'è un'eccezione: GNU catnon bufferizza mai il suo output. Non utilizza stdioo modifica la stdiopolitica di buffering predefinita .
Posso essere abbastanza sicuro che stai usando GNU cate non qualche altro unix catperché gli altri non si comporteranno in questo modo. Unix tradizionale catha -uun'opzione per richiedere output senza buffer. GNU catignora l' -uopzione perché il suo output è sempre senza buffer.
Quindi ogni volta che si ha una pipe con a catsulla sinistra, nel sistema GNU, il passaggio dei dati attraverso la pipe non sarà ritardato. Non catsta nemmeno andando riga per riga: il tuo terminale lo sta facendo. Mentre digiti input per cat, il tuo terminale è in modalità "canonica" - basata su linea, con tasti di modifica come backspace e ctrl-U che ti offrono la possibilità di modificare la linea che hai digitato prima di inviarlo con Enter.
Nel cat|tr|sedesempio, trè ancora ricevere dati da catappena si preme Enter, ma trsta seguendo il stdiocriterio predefinito: la sua uscita sta per un tubo, in modo che non filo dopo ogni riga. Scrive sulla seconda pipe quando il buffer è pieno o quando viene ricevuto un EOF, a seconda di quale evento si verifica per primo.
sedsta anche seguendo la stdiopolitica di default, ma il suo output sta andando su un terminale, quindi scriverà ogni riga non appena avrà finito con esso. Questo ha un effetto su quanto devi digitare prima che qualcosa appaia sull'altra estremità della pipeline - se il sedbuffering del blocco fosse il suo output, dovresti digitare il doppio (per riempire tril buffer di output e sed l'output buffer).
GNU sedha -uun'opzione, quindi se si inverte l'ordine e si utilizza cat|sed -u|tr, l'output verrà visualizzato di nuovo immediatamente. (L' sed -uopzione potrebbe essere disponibile altrove ma non credo che sia un'antica tradizione unix come cat -u) Per quanto posso dire non esiste un'opzione equivalente per tr.
Esiste un'utilità chiamata stdbufche consente di modificare la modalità di buffering di qualsiasi comando che utilizza le stdioimpostazioni predefinite. È un po 'fragile poiché utilizza LD_PRELOADper realizzare qualcosa che la libreria C non è stata progettata per supportare, ma in questo caso sembra funzionare:
cat | stdbuf -o 0 tr '[:lower:]' '[:upper:]' | sed 'p'
catbuffering fino alla chiusura di stdin.