Linux Shell - reindirizzamento I/O

Continuiamo la nostra guida alla Shell di Linux e iniziamo a fare qualcosa di interessante: il reindirizzamento input/output di comandi per creare una sorta di catena di montaggio e generare comandi complessi.
Fino ad ora abbiamo visto numerosi comandi che generano un output. Quello che non abbiamo mai detto è che esistono in realtà due tipi differenti di output: standard output (stdout) e standard error (stderr). Allo stesso tempo, molti comandi sfruttano uno standard input (stdin) per ricevere dei parametri. Questi tre canali sono individuati dal sistema operativo come file descriptor, ovvero degli interi (rispettivamente 0, 1 e 2 per stdin, stdout, stderr) che si riferiscono a file aperti da un processo.
Il reindirizzamento input/output ci permette di manipolare proprio queste tre file descriptor per definire da dove vengono gli input e dove vanno a finire gli output.

Reindirizzamento dello Standard Output

Il carattere > ci permette di definire un reindirizzamento dello standard output, ad esempio per salvare l'output di un comando su file.

ls > output.txt

Con questo comando infatti salveremo sul file output.txt la lista dei file presenti nella cartella corrente. Notate che visto che abbiamo redirezionato l'output verso il file, questo non verrà stampato in console. Fate attenzione, perchè in questo modo il file output.txt verrà sovrascritto ad ogni chiamata. Se volete invece appendere l'output ad un file già esistente potete usare >>:

ls >> output.txt

Reindirizzamento dello Standard Error

Provando a redirezionare un comando che fornisce un errore, noterete che otterete un output in console e niente verrà scritto su file. Questo è perché il messaggio è diretto verso lo standard error. Per reindirizzare lo standard error occorre fare riferimento al suo file descriptor con 2> nel seguente modo:

ls 2> error.txt

Per reindirizzare entrambi gli stream di standard output e error basta effettuare due reindirizzamenti. Prima il classico reindirizzamento di stdout su file e poi stderr su stdout. La notazione per reindirizzare un file descriptor su un altro è 2>&1:

ls > outputerror.txt 2>&1

Occorre tenere a mente che l'ordine dei reindirizzamenti è importante, altrimenti lo standard error verrà reindirizzato verso lo schermo invece che su file.

Qualora voleste sbarazzarvi di un output (stdout o stderr) potete reindirizzarlo verso un file speciale chiamato /dev/null. Questo è un file che riceve input e lo elimina.

ls > /dev/null

Reindirizzamento dello Standard Input

Analogamente a quanto avviene per lo standard output, è possibile reindirizzare lo standard input usando <. Per capirne il funzionamento introduciamo il comando cat: questo comando legge una lista di file e li copia nello standard output. Possiamo usare > per scrivere direttamente su file ma allo stesso tempo possiamo usare < per scegliere cosa dare in input al comando stesso. In questo modo invece di ricevere input da tastiera, lo riceverà dal file scelto.

Pipeline

Uno degli strumenti più utili lavorando con la Shell è la possibilità di creare delle pipeline, ovvero una sequenza di comandi che operano sull'ouput del precedente. Per mettere in cascata due comandi basta utilizzare il simbolo | (pipe).

ls | less

Questo comando ad esempio effettuerà ls ma aprirà la lista dei file presenti nella directory con l'editor testuale less.
L'utilità delle pipeline è quella di poter effettuare dei filtri sugli output di altri comandi, in modo da produrre output più semplici o più strutturati. Vediamo una lista di comandi utili da utilizzare in pipline.

  • uniq
  • : elimina righe ripetute nell'output. È spesso utile se utilizzato in combinazione con il comando sort per ordinare le righe.

    ls /bin /usr/bin | sort | uniq
    
  • wc
  • : conta il numero di righe, parole e byte dell'output.

    ls | wc
    
  • grep
  • : uno dei comandi più utili che incontrerete. Serve a trovare un pattern all'interno di un file. Ne avevamo già parlato in precedenza, per approfondire leggete QUI.

    ls | grep txt
    
  • head
  • : mostra solamente le prime 10 linee di un file. Utile se vogliamo ispezionare un file o un output molto grande.

    ls | head
    
  • tail
  • : è l'opposto di head, in quanto mostra solamente le ultime 10 linee di un file. Utile se vogliamo ispezionare un file o un output molto grande.

    ls | tail
    

    In particolare è utile se vogliamo tenere sotto controllo un file di log in cui un processo sta scrivendo. Usando il flag -f infatti l'output di tail si aggiornerà appena il file in analisi viene modificato.

    tail -f /var/log/messages
    
  • tee
  • : legge lo standard input e lo copia sia sulle standard output che su uno o più file.

    ls | tee output.txt | grep txt
    

    Con questo comando salveremo l'output su ls su file ma allo stesso tempo possiamo effettuare un filtro utilizzando grep per generare sullo standard output la lista dei file testuali nella cartella.

Federico Becattini

Dottorando in computer vision. Appassionato di informatica e elettronica fai da te, specialmente se per applicazioni futili. Tormenta i suoi amici e colleghi con idee geniali spesso non riconosciute come tali.

Linux Shell - reindirizzamento I/O ultima modifica: 2017-11-28T15:43:20+00:00 da Federico Becattini


Advertisment ad adsense adlogger