lunedì 12 dicembre 2011

I/O

 Salve!

Oggi ci cimenteremo con nomi di questo calibro: stdin, stdout, stderr, descrittore di file.
A parte l'espressione "descrittore di file" il resto potrebbe sembrare un pò tedesco. :) Dimenticavo, ci sarebbe anche questo: I/O 

Partiamo da lontano, da molto lontano.

Il pc, ma non solo il pc, è costituito da dispositivi input e dispositivi output.


L'insieme di questi dispositivi viene detto "I/O", cioè dispositivi input/output.

Anche la mia chitarra elettrica è costituita da un dispositivo input (le corde) e da un dispositivo output (le casse).
Tengo a precisare che tutte le chitarre elettriche sono dotati di questi dispositivi. :D

Nel pc, giusto per fare un esempio, i dispositivi input sono il mouse e la tastiera; mentre i dispositivi output sono il monitor, la stampante, etc.


Facciamo un altro passettino in avanti (lo spero)

Apro un terminale e scrivo:

$ echo "oggi il mondo va a scatti"

Non ho fatto altro che prendere il comando "echo" e dargli in pasto una frase.

Mi chiedo, con quale strumento ho scritto la frase?

Risposta: la tastiera.

Com'è definita la tastiera in un pc? 
Risposta: Dispositivo input, cioè dispositivo di immissione dati. Eccoci così alla chiarificazione del primo termine arcano, stdin.
Stdin sta per standard input. La tastiera in Linux è uno standard input, cioè è l'input predefinito.

Se dopo aver scritto echo “oggi il mondo va a scatti” premo invio, ciò che ho scritto viene stampato a video. Eccoci alla chiarificazione del secondo termine arcano, stdout.
Il monitor in linux è lo standard output, l'output predefinito. Dunque stdout sta per standard output.

Può succedere che un comando, per svariati motivi, emetta degli errori. Eccoci al terzo termine arcano, stderr, cioè standard error. Se lo standard input è la tastiera, lo standard output è il monitor, quale sarà lo standard error? Risposta: Pure il monitor :D

Bene, standard error e standard output, in linea di massima, coincidono. In altri termini, il risultato di un comando e i suoi eventuali errori vengono stampati entrambi a video.
Estrema sintesi. Un comando richiede un input, questo input glielo do tramite la tastiera (standard input), il comando elabora l'input e restituisce un risultato o un eventuale messaggio di errore.
Sia il risultato del comando che l'eventuale messaggio di errore hanno una destinazione predefinita che è il monitor (standar output e standard error). Chiaro? :)

Chiariti questi concetti generali, passiamo alla redirezione. La redirezione potrei definirla come, a scanso di equivoci, "dirottamento". :)

Vabbè, facciamo un altro passettino in avanti.

Essì, con la redirezione vado a stravolgere ciò che è predefinito: La tastiera non sarà più l'input predefinito e il monitor non sarà più lo standard output e/o lo standard error.

Prima di passare a qualche esempio per chiarire tutto in pochi secondi, devo, purtroppo, introdurre un altro argomento, il quarto termine arcano: Il descrittore di file.
Il descrittore di file altro non è che un numero che il sistema operativo assegna ad un file aperto per tenerne traccia. Lo si consideri una versione semplificata di un puntatore ad un file. Tengo a ribadire che questa definizione l'ho letteralmente "fregata". Non sarei mai riuscito ad essere così chiaro :D

I descrittori di file per stdin, stdout e stderr sono, rispettivamente, 0, 1 e 2. Non dico, invece, che ci sarebbero altri descrittori, che in tutto sono 9 etc etc. :D

provate a digitare

$ ls -l /dev/std*

Per il momento tralasciamo!

Passiamo finalmente agli esempi.


                                      Redigere lo stdout nel file "prova.txt"

$ echo "la terra va a scatti" > prova.txt

Oppure

$ echo "la terra va a scatti 1>prova.txt

per vedere il risultato,

$ cat prova.txt

NB. Tenete presente che se il file "prova.txt" non esiste, viene creato, se esiste viene sovrascritto.

Per evitare la sovrascrizione si usa quest'altro segno ">>"

$ echo "la terra va a scatti" >> prova.txt.

oppure

$ echo "la terra va a scatti" 1>> prova.txt

NB. Anche in questo caso, se il file non esiste viene creato, ma se esiste la frase viene semplicemente accodata. :)

Da tenere presente:

1. Redirigere “niente” verso un file esistente equivale a svuotarlo.

$ > file_esistente

2. redigere "niente" verso un file inesistente creerà un nuovo file vuoto con il nome indicato

$ > file_inesistente

                                Redigere lo stderr nel file prova1.txt

Cerchiamo, ad esempio, di leggere un file che non esiste

$ cat felicità.txt

la shell ci restituirà il seguente messaggio:

cat: felicità.txt: File o directory non esistente

Ora, per redirigere questo messaggio in un documento di testo,

$ cat felicità.txt 2> prova1.txt

per controllare

$ cat prova1.txt

NB.  Se il file non esiste viene creato, se esiste viene sovrascritto.

$ cat felicità.txt 2>> prova1.txt

NB. In tal caso se il file non esiste viene creato, ma esiste, l'errore viene semplicemente accodato.

                  Redirigere sia lo stdout che lo stderr in file di testo


$ nome-comando &> prova3.txt

oppure

$ nome-commando > prova3.txt 2>&1


                              Redirigere l’input da un file

$ comando < nome_file

esempio: $ grep parola_da_cercare < file.txt
  
In tal caso il risultato verrà stampato sul terminale.


                                                   /dev/null

/dev/null, null device, è un file  non fisicamente presente su memoria di massa. Il suo compito è quello di non memorizzare i dati che gli vengono scritti.

Primo esempio:

$ comando 1>/dev/null

$ echo "la terra va a scatti" 1>/dev/null

viene ignorato il risultato (output di un comando)

Secondo esempio:

$ comando 2>/dev/null

Vengono ignorati i messaggi di errori di un comando.

Lanciate dal terminale un comando che non esiste seguito da 2>/dev/null

$ marmitta 2>/dev/null

vedrete che il messaggio di errore si perde nel nulla :)

Terzo esempio:

$ command > /dev/null 2>&1

In questo modo si redirige verso /dev/null non solo i messaggi di errori ma anche l'output del comando.

Alla prossima!

Io e Lightuono


7 commenti:

  1. Bel post! Completo e molto chiaro :)

    RispondiElimina
  2. Bravo. Manca solo la pipe (o il pipe non so mai a mettere il genere giusto) che sarebbe poi questo | e si potrebbe parlare dei filtri. Ma forse ho svelato la continuazione --se sì cancella tutto con i poteri che ti da blogspot :-D

    RispondiElimina
  3. Di queste cose se ne occuperà il socio :D :D

    RispondiElimina
  4. Si legge in un fiato: post potente, chiaro e lineare. Complimenti, un piacere leggerlo :)

    RispondiElimina
  5. Ciao posso farvi una domanda a riguardo?
    Se io ho una directory vuota e scrivo cat pippo.txt ottengo ovviamente "cat: pippo.txt: No such file or directory"
    Ma se scrivo invece cat pippo.txt 2> pippo.txt il file pippo.txt risulterà comunque vuoto nonostante abbia redirezionato lo standard error proprio sul file?

    RispondiElimina