Pensavo di aver visto tutto in UNIX. Questa domanda mi ha schiaffeggiato dal mio compiacimento. Che bella domanda!
tail
mostra le ultime X linee. tail -f
fa lo stesso, ma essenzialmente in un ciclo infinito: all'avvio, mostra le ultime X linee del file, quindi usa un po 'di magia del sistema operativo (come inotify), monitora e mostra nuove linee.
Per fare il suo lavoro, tail
deve essere in grado di individuare la fine del file. Se tail
non riesce a trovare la fine del file, non può mostrare le ultime X righe, perché "last" non è definito. Quindi cosa fa tail
in questo caso? Attende fino a quando non trova la fine del file.
Considera questo:
$ chatter() { while :; do date; sleep 1; done; }
$ chatter | tail -f
Questo non sembra mai fare progressi, perché non c'è mai una fine definita del file da chatter
.
Ottieni lo stesso comportamento se chiedi tail
di darti le ultime righe da una pipe del file system. Ritenere:
$ mkfifo test.pipe
$ tail test.pipe
stdbuf
aggirare il problema percepito era un nobile tentativo. Il fatto chiave è che il buffering I / O non è la causa principale: la mancanza di un end-of-file definito è. Se controlli il codice sorgente tail.c , vedrai che il file_lines
commento della funzione recita:
END_POS è l'offset del file di EOF (uno più grande dell'offset dell'ultimo byte).
e questa è la magia. È necessario un end-of-file per far funzionare tail in qualsiasi configurazione. head
non ha questa limitazione, ha solo bisogno di un inizio di file (che potrebbe non avere, prova head test.pipe
). Strumenti orientati allo streaming come sed
e awk
non necessitano né di un inizio né di una fine del file: funzionano su buffer.