Comando tail di Linux
Il comando tail di Linux è uno degli strumenti essenziali della riga di comando. Principalmente, il comando è usato per mostrare la fine di un file (di testo) o per limitare l’output di un comando Linux a un determinato ambito. Questo mette il comando tail di Linux in linea con il comando head di Linux e i comandi ‘cat’ e ‘less’. I precedenti comandi di Linux sono tutti usati per mostrare il contenuto dei file di testo.
Il comando tail di Linux fa parte delle GNU Core Utilities (Coreutils). È una raccolta di comandi di base per la riga di comando, che sono inclusi nel sistema operativo open source di Linux. Le coreutils sono rilasciate con una licenza open source e sono disponibili per il download per una varietà di sistemi operativi diversi.
Perché si utilizza il comando tail di Linux
La funzionalità di base del comando tail di Linux è quella di visualizzare la fine di un file. Per fare questo, dovete sapere che i dati scritti in un file finiscono alla fine del file. Così il comando tail di Linux ci permette di controllare se sono stati aggiunti nuovi dati a un file. Pertanto, il comando tail di Linux è comunemente utilizzato per analizzare i file di log e monitorarli.
Molti programmi, specialmente server web come Apache o nginx scrivono informazioni di stato nei cosiddetti file di log. Nel caso dei log del server, questi file contengono, per ogni riga, una marca temporale, l’URL della risorsa richiesta, l’indirizzo IP del richiedente e altre informazioni. Crescono progressivamente a ogni richiesta e, per limitare le dimensioni oltre una certa soglia, i file di log sono di solito “ruotati”. Vengono compressi e archiviati con un nuovo nome. Inoltre, viene creato un nuovo file di log vuoto con il nome originale. Illustriamo di seguito una panoramica dei comuni file di log sotto Ubuntu Linux:
File di log di Ubuntu Linux | Spiegazione |
/var/log/auth.log | Registro di autorizzazione di Linux |
/var/log/daemon.log | Registro del demone di Linux |
/var/log/debug | Registro di debug di Linux |
/var/log/kern.log | Registro del kernel Linux |
/var/log/syslog | Registro di sistema di Linux |
/var/log/apache2/access.log | Accessi ai contenuti web del server web Apache2 |
/var/log/apache2/error.log | Messaggi di errore del server web Apache2 |
Il comando tail di Linux sulla riga di comando
Il comando tail di Linux viene eseguito sulla riga di comando. Come al solito, si inserisce il nome del comando seguito da parametri opzionali e infine si aggiunge il nome o il percorso di uno o più file. Per prima cosa, guardiamo la notazione del caso generale:
tail [opzioni] <file>
Senza opzioni, il richiamo più semplice del comando tail di Linux è rappresentato dal seguente schema:
tail <file>
Richiamato in questo modo, il comando tail di Linux mostra le ultime dieci righe del file specificato. Questo è utile per visualizzare i dati più recenti scritti nel file.
Opzioni di base del comando tail di Linux
Il comando tail di Linux può essere controllato da parametri. Come parte delle GNU Coreutils, c’è una forma lunga per ogni opzione. C’è anche una forma breve per le opzioni usate più comunemente, spesso motivate storicamente. Illustriamo di seguito una panoramica delle opzioni più utili:
Opzione (forma breve / forma lunga) | Spiegazione |
-n / --lines | Limita l’output alle ultime n righe / Limita l’output alle righe che seguono dalla riga n in poi |
-c / --bytes | Limita l’output agli ultimi n byte / Limita l’output ai byte che seguono dal byte n in poi |
-q / --quiet, --silent | Sopprime l’output dei nomi dei file quando viene usato con più file |
-v / --verbose | Forza l’output dei nomi dei file quando viene usato con più file |
--help | Mostra informazioni ausiliarie del comando |
--version | Mostra informazioni sulla versione del comando |
Il comando tail di Linux è progettato principalmente per l’uso con file di testo nel set di caratteri ASCII. Per questi, un carattere corrisponde esattamente a un byte. Se si elaborano file nel set di caratteri Unicode con l’opzione ‘-c’ del comando tail di Linux, potrebbero verificarsi effetti secondari inaspettati.
Opzioni avanzate del comando tail di Linux
Le opzioni di base del comando tail di Linux descritte sopra funzionano analogamente al comando head. Tuttavia, mentre il comando head mostra l’inizio del file, il comando tail di Linux mostra la fine. Ma il comando può essere usato in molti altri modi e, nello specifico, offre svariate opzioni per monitorare modifiche ai file. Con questo comando, i dati aggiunti alla fine del file possono essere visualizzati continuamente. Pertanto, è particolarmente adatto al monitoraggio dei file di log. Questo processo è anche noto come “live tail”. Illustriamo di seguito una panoramica delle opzioni più comunemente usate:
Opzione (forma breve / forma lunga) | Spiegazione |
-f / --follow=[{name|descriptor}] | Monitora le modifiche al file e visualizza continuamente nuovi dati scritti alla fine del file. Senza specificare un valore dopo ‘--follow=‘, ‘descriptor’ è usato come valore predefinito. Questo significa che la live tail continuerà a funzionare anche se il file viene rinominato o spostato. |
-F | Corrisponde alla chiamata con --follow=name --retry; l’effetto è che la live tail continua a funzionare anche se il file originale viene rimosso durante la rotazione dei log e sostituito con un nuovo file con lo stesso nome. |
-s / --sleep-interval=N | Output del file lasciato inattivo per il numero di secondi specificato. |
--retry | Prova a riaprire un file non disponibile appena diventa di nuovo disponibile. È particolarmente utile in combinazione con l’opzione ‘--follow=name’ per continuare a monitorare il nuovo file con lo stesso nome dopo la rotazione di un file di log. |
--pid=PID | Se usato con l’opzione -f, il comando tail termina quando il processo con l’ID di processo specificato si conclude. Utile per annullare la live tail quando il programma che scrive sul file si chiude. |
Esempi di utilizzo del comando tail di Linux
Nella documentazione di coreutils, il comando tail di Linux è riportato nella sezione “Output of parts of files” (Visualizzazione di parti di file). Dovete sapere che il termine “file” è molto ampio. Più preciso è il termine “flussi di testo”.
Seguendo la filosofia Unix, i comandi da riga di comando usano flussi di testo come formato universale di input e output. I flussi di testo sono soprattutto file, ma anche input e output standard della riga di comando. Inoltre, le cosiddette “pipe”, che in italiano significa all’incirca “tubi”, sono di grande importanza. Queste permettono di concatenare più comandi. In questo caso, l’output di un comando viene passato come input al comando successivo.
L’idea di fondo di concatenare diversi comandi insieme risale alla filosofia Unix. Invece di sviluppare comandi complessi per compiti completamente diversi, c’è un insieme relativamente gestibile di comandi generali. Seguendo la massima “do one thing, and do it well” (“fai una cosa e falla bene”), ogni comando ha una funzionalità strettamente definita. I comandi utilizzano i flussi di testo come interfaccia universale e possono essere combinati per creare soluzioni sempre nuove.
Negli esempi seguenti, quando chiamiamo il comando tail di Linux, usiamo le opzioni nella forma abbreviata (‘-n’ invece di ‘--lines’, ecc.) Se leggete altra documentazione o esempi di codice, incontrerete questo uso frequentemente.
Esempi di utilizzo generali del comando tail di Linux
I seguenti esempi generali usano le opzioni di base del comando tail di Linux presentate all’inizio. Per gli esempi che usano le opzioni avanzate, potete consultare il paragrafo sul monitoraggio dei file di log che trovate più avanti. La maggior parte degli esempi illustrati combinano il comando tail di Linux con uno o più altri comandi di Linux. Le pipe sopra menzionate si impiegano per utilizzare l’output di un comando come input del comando successivo.
Usare il comando tail di Linux per visualizzare la fine di un file
Nel caso più semplice, usiamo il comando tail di Linux per mostrare le ultime righe di un file. Per provarlo, sostituite il segnaposto ‘<file>‘ con il nome o il percorso di un file di testo presente sul vostro sistema. Di seguito usiamo l’opzione -n e visualizziamo le ultime tre righe di un file:
tail -n 3 <file>
È spesso utile tenere sotto controllo il contesto del file elaborato dal comando tail di Linux. Per visualizzare le righe con i numeri di riga, prima elaboriamo il file con il comando nl (il nome deriva da “line numbering”, ovvero “numeri di riga”) e instradiamo l’output tramite pipe al comando tail di Linux:
nl <file> | tail -n 3
Visualizzare gli ultimi comandi usati sulla riga di comando
Il comando history visualizza i comandi inseriti sulla riga di comando. Spesso si è interessati solo alle ultime chiamate. Inoltre, un output completo della cronologia dei comandi può rivelare dati sensibili. In questo esempio instradiamo l’output del comando history al comando tail di Linux e visualizziamo le ultime cinque righe:
history | tail -n 5
Usare il comando tail di Linux per cancellare i file di backup più vecchi in una directory
Vediamo un esempio più complesso. Cancelleremo i dieci file più vecchi da una directory con file di backup. Per fare questo, usiamo i quattro comandi Linux ‘ls’, ‘tail’, ‘xargs’ e ‘rm’:
ls -t *.bak | tail | xargs rm
Cosa succede esattamente?
- Il comando ls elenca i file presenti in una directory.
Con l’opzione ‘-t’, i file vengono ordinati per data di modifica. I file più vecchi sono in fondo alla lista.
Usiamo il motivo di ricerca ‘*.bak’ per l’origine dati. In pratica, si tratta di un’estensione comunemente utilizzata per i file di backup. Inoltre, serve come protezione in modo da non cancellare accidentalmente i file importanti quando li richiamate.
Trasmettiamo tramite pipe l’elenco dei file al comando tail di Linux.
- Usando il comando tail di Linux senza specificare alcuna opzione, leggiamo gli ultimi dieci file dell’elenco. I nomi dei file di output sono i file più vecchi della directory.
- Il comando xargs riceve una lista di file e il nome di un comando. Il comando viene eseguito passando i file come argomenti.
Nel nostro esempio, il comando tail di Linux restituisce un testo con più righe. Ogni riga contiene il nome di un file da cancellare. Tramite ‘xargs’ i nomi dei file sono staccati dalle righe e trasmessi come argomenti al comando rm.
- Per cancellare i file sotto Linux, si ricorre al comando rm. Questo comando cancella i file trasmessi come argomenti.
Si noti che i file non vengono spostati nel cestino, ma cancellati immediatamente.
È consigliabile fare attenzione quando si procede alla cancellazione dei file sulla riga di comando di Linux. Affinché possiate provare il nostro esempio senza preoccupazioni, dovreste prima creare una directory con dei file di prova. Per farlo, eseguite il seguente codice sulla riga di comando:
mkdir ~/Desktop/tail-test/
cd ~/Desktop/tail-test/
touch test-{1..100}.bak
Per prima cosa, creiamo una directory di prova ‘tail-test/’ sul desktop e passiamo a quella directory. Poi creiamo 100 file di prova vuoti con i nomi da ‘test-1.bak’ a ‘test-100.bak’. Quindi eseguite il codice per cancellare i dieci file più vecchi:
ls -t ~/Desktop/tail-test/*.bak | tail | xargs rm
Usare il comando tail di Linux per monitorare le modifiche ai file di log del server
Finora abbiamo visto il funzionamento generale del comando tail di Linux. Negli esempi seguenti, ci concentriamo sul monitoraggio dal vivo dei file di log del server (“live tail”).
In questi esempi, partiamo dal server web Apache2 su Ubuntu Linux. I file di log si trovano nella directory ‘/var/log/apache2/’. Su altre distribuzioni Linux, il percorso potrebbe essere diverso. Lo stesso vale per altri server web, come nginx.
Eventualmente solo l’utente root ha accesso alla directory con i file di log. In questo caso, è necessario eseguire i comandi con ‘sudo’.
Usare il comando tail di Linux per monitorare le modifiche a un file di log del server
Una normale chiamata al comando tail di Linux visualizza una volta il numero specificato di righe di un file. Se in seguito vengono aggiunti nuovi dati alla fine del file, il comando deve essere eseguito di nuovo. Esattamente per questo caso ci sono altre opzioni. Queste istruiscono il comando a monitorare le modifiche a un file e a mostrarle continuamente.
Vediamo come funziona usando il log di accesso al server web Apache2 come esempio. Eseguiamo il comando tail di Linux con l’opzione -f e passiamo il nome del file di log:
tail -f /var/log/apache2/access.log
Quando viene chiamato in questo modo, le modifiche al log di accesso vengono visualizzate continuamente. Questo approccio non è pratico in caso di numerosi accessi per unità di tempo. In questo caso, il registro cambia così rapidamente che il terminale viene inondato di dati. Premete la combinazione di tasti ‘Ctrl+C’ per annullare l’attuale esecuzione della live tail.
Richiamato con l’opzione ‘-f’, il comando tail di Linux controlla il file specificato. Se questo viene rimosso, l’output viene interrotto. Come spiegato all’inizio, i file di log vengono ruotati periodicamente. Viene quindi creato un nuovo file con il vecchio nome. Per continuare a monitorare un file di log nonostante la rotazione, usiamo l’opzione -F:
tail -F /var/log/apache2/access.log
Usare il comando tail di Linux per monitorare le modifiche a più file di log del server
Finora abbiamo usato il comando tail di Linux per elaborare un singolo file. Tuttavia, il comando permette anche di monitorare più file contemporaneamente. Di seguito usiamo lo schema di ricerca ‘*.log’ per monitorare continuamente tutti i file con estensione ‘.log’:
tail -F /var/log/apache2/*.log
Ci sono altre due opzioni per elaborare più file. Per prima cosa, possiamo usare l’opzione ‘-q’ per sopprimere l’output dei nomi dei file:
tail -q -F /var/log/apache2/*.log
Allo stesso modo, l’opzione -v può essere usata per forzare l’output dei nomi dei file, il che ha senso se lo schema di ricerca restituisce solo un singolo file:
tail -v -F /var/log/apache2/*.log
Usare il comando tail di Linux per monitorare modifiche specifiche a un file di log del server
Negli esempi precedenti, abbiamo monitorato qualsiasi modifica a un file di log. Più comune, tuttavia, è la restrizione a certe modifiche. Per limitare l’output delle modifiche di un file di log a uno schema di ricerca, si usa il comando grep. È illustrato di seguito un esempio generale di questo approccio:
tail -F /var/log/apache2/access.log | grep <schema>
In particolare, è spesso utile monitorare un log del server per gli accessi da un particolare indirizzo IP. Questo può essere efficace, ad esempio, per determinare se un attacco a un server è già stato completato o è ancora in corso. In questo esempio monitoriamo il log di accesso del server web Apache per le richieste provenienti dall’indirizzo IP ‘93.184.216.34’:
tail -F /var/log/apache2/access.log | grep '93.184.216.34'
In questo caso usiamo l’indirizzo IP del dominio di esempio ‘example.com’. Se un log di accesso lo contiene davvero, molto probabilmente si tratta di un indirizzo IP falsificato.
Guardiamo un altro scenario di distribuzione comune. Invece di filtrare il log di accesso per indirizzo IP, monitoriamo gli accessi a una risorsa specifica. Un accesso al file ‘robots.txt’ indica le richieste dei bot dei motori di ricerca. Di nuovo, facciamo uso del comando grep. Eseguendo la chiamata in questo modo, vengono visualizzati solo i nuovi accessi dai bot dei motori di ricerca:
tail -F /var/log/apache2/access.log | grep 'robots.txt'