Perché “tail -f… | tail "non riesci a produrre alcun output?


36

Perché il seguente comando non produce alcun output?

$ tail -f /etc/passwd | tail

Dopo aver letto sul buffering , ho provato inutilmente quanto segue:

$ tail -f /etc/passwd | stdbuf -oL tail

Si noti che quanto segue produce output:

$ tail /etc/passwd | tail

Quindi fa questo:

$ tail -f /etc/passwd | head

Sto usando la versione di coda 8.21 (GNU coreutils).


17
Quali sono le ultime 10 cifre di π?
Keith Thompson,

Risposte:


15

Pensavo di aver visto tutto in UNIX. Questa domanda mi ha schiaffeggiato dal mio compiacimento. Che bella domanda!

tailmostra le ultime X linee. tail -ffa 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, taildeve essere in grado di individuare la fine del file. Se tailnon riesce a trovare la fine del file, non può mostrare le ultime X righe, perché "last" non è definito. Quindi cosa fa tailin 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 taildi darti le ultime righe da una pipe del file system. Ritenere:

$ mkfifo test.pipe
$ tail test.pipe

stdbufaggirare 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_linescommento 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. headnon ha questa limitazione, ha solo bisogno di un inizio di file (che potrebbe non avere, prova head test.pipe). Strumenti orientati allo streaming come sede awknon necessitano né di un inizio né di una fine del file: funzionano su buffer.


37

tail -fLa coda è in realtà qualcosa di sconosciuto nel presente, quindi come dovrebbe tailsaperlo il prossimo . D'altra parte tail -fla testa è qualcosa di già noto e potrebbe quindi essere processato.

O per dirla più semplice: tailè relativo alla fine del file, ma il flusso di output di tail -fnon ha ottenuto EOF (almeno non prima della sua chiusura).

Se si trova il primo tail's pid e uccidere, si dovrebbe quindi vedere l'uscita dal secondo.


21

Risposta tecnica

Quando viene eseguito con un flusso come input, tailmantiene un nbuffer di riga che riempie mentre legge il flusso, ma non può emettere quelle linee fino a quando non raggiunge la fine del flusso, ovvero riceve un EOFcodice speciale quando tenta di leggere dall'input streaming. L'invocazione tail -fnon esce, quindi non chiuderà mai il suo flusso, il che rende impossibile ad esempio restituire le ultime 10 righe di quel flusso.


3

La funzione di tailè mostrare l'ultima parte - "coda" - dell'input o del file. (L'opzione -friguarda ciò che fa in seguito, quindi non è rilevante qui.)

Pensiamo a un file:

Qual è l' ultima parte di un file ?
Diciamo che sono le ultime n righe di un file.

Quando leggiamo la riga idel file di input, come decidere se deve essere stampato o no?
Non sappiamo se sia nell'ultima parte, perché non sappiamo quale sarà l'ultima riga. Quindi non possiamo stamparlo ora.

Dobbiamo mantenere la linea fino a quando non diventa chiaro che fa parte delle ultime nlinee o non può più farne parte, perché conosciamo nulteriori linee

Se ora arriviamo alla fine del file , sappiamo che le ultime nrighe che abbiamo mantenuto sono in realtà le ultime nrighe del file.

Ora, nel caso di

tail -f /etc/passwd | tail

il primo taillegge il file, quindi attende di ottenere più dati da esso, per scriverlo anche. Quindi non segnalerà la fine del file alla seconda coda quando si arriva alla fine del file che legge. Senza questo, il secondo tail non viene mai informato della fine del file, quindi non può mai scoprire quali sono le ultime righe che dovrebbe stampare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.