lunedì 12 settembre 2011

Progetto Bash: IF - Exit status

Salve!

Dato che sono trascorsi più di due mesi dall'ultimo post teorico sul progetto bash cerco, in qualche modo, di richiamare alla mente alcuni concetti cardini, per poi continuare con nuovi argomenti.

Volendo trarre delle considerazioni dai post che abbiamo scritto finora, possiamo dire che
  • lo script può consistere in una semplice sequenza di comandi
  • uno script più avanzato richiede (necessariamente?!) di un costrutto condizionale.


Cos'è un costrutto condizionale?
immaginiamo di trovarci in una zona turistica  e che vogliamo raggiungere, con la nostra auto, il primo centro abitato, che dista dal nostro hotel una quarantina di chilometri.
Posto che
  • siamo sprovvisti di navigatore satellitare
  • la segnaletica stradale lasci molto a desiderare
  • quel giorno, per il troppo caldo, non incontriamo alcuna persona cui chiedere informazione (che sfiga!), 
dopo una ventina di chilometri arriviamo ad un incrocio! Che strada prendiamo? Andiamo a destra o a sinistra? Qual'è la strada che ci condurrà alla nostra località? Vabbè, non dovete rispondere, sono domande (molto) retoriche!

L'IF, in uno script, si trova nelle nostre stesse condizioni! Con una sola sostanziale differenza: L'IF, a differenza di noi, una sorta di "insegna stradale" ce l'ha.

Questa "insegna" è il comando test ---> [

Ve lo ricordate?


Il comando test, (come già sappiamo) valuta delle espressioni.

Quali espressioni?

Le espressioni create da noi secondo una certa sintassi, ovvio. E in base alla nostra espressione, che il comando test valuterà, il costrutto IF prenderà una decisione (es. svolto a sinistra). Decisione che determinerà il prosieguo dello script!

In cosa consistono queste espressioni?

Vi consiglio vivamente di leggere il primo post sull'IF (qui) con la conseguente parte pratica (qui).
In quei post si diceva che l'espressione può consistere, ad es., in un confronto tra variabili oppure nella valutazione dell'esistenza di un file. E che, in questo confronto o in questa valutazione, si fa uso di un operatore di confronto.

Bene! Richiamati questi concetti di cui abbiamo già largamente discusso, scendiamo un pò più a fondo nel nostro ragionamento.

Ogni qualvolta lanciamo un comando nella nostra shell, lo stesso esegue delle operazioni. Terminata l'operazione, il comando verrà tradotto in un codice. Il c.d. codice di uscita o exit status!
Il codice di uscita è un numero compreso tra 0 e 255.
Ora, solo se l'exit status sarà pari a zero (0), il comando avrà avuto successo, in caso contrario si parlerà di un suo fallimento. 
Detto così potrebbe sembrare estremamente difficile, ma non lo è.
In bash una cosa può essere vera o falsa. Non ci sono alternative.
  • Se è vera, avrà successo e l'exit status sarà pari a zero; 
  • Se è falsa, non avrà successo e l'exit status sarà diverso da zero.
Facciamo un esempio. Nell'ultimo posto teorico (che risale al 6 luglio) qui, ma anche nell'ultimo post pratico (che è stato scritto di recente) qui, abbiamo parlato degli operatori logici OR e AND. Urge una lettura di entrambi i post.

Già sappiamo che, in uno script, OR e AND vengono indicati con -o (OR) e -a (AND), tuttavia possono essere indicati diversamente: && (AND) e || (OR). Nel prossimo post teorico diremo quando nel costrutto IF si ricorrerà a questa diversa nomenclatura.

Ritorniamo al nostro discorso sull'exit status.

Creiamo una directory nella nostra home e poi spostiamoci al suo interno.

Per fare questo utilizzermo l'operatore AND, scritto però secondo la "nuova" nomenclatura.

$ mkdir bit && cd bit

Ormai è assodato come ragiona l'operatore AND. Solo se il primo comando avrà successo, sarà eseguito anche il secondo.

Detto diversamente, l'operatore && starà molto attento al fatto che mkdir crei o meno la cartella bit nella directory home. E solo se la crea, eseguirà il comando cd.

Aspettate! In quale caso mkdir non creerà la cartella bit?
Solo se la cartella bit è già presente! Vedete?

bit3lux@bit3lux:~$ mkdir bit && cd bit
mkdir: impossibile creare la directory "bit": Il file esiste

In questo caso l'exit status di mkdir (codice di uscita) sarà diverso da zero, che vuol dire, in altri termini, che il comando mkdir non ha avuto successo e che  && (operatore AND) non ha eseguito il comando cd. Infatti si resterà nella directory corrente. Chiaro?

Il discorso contrario si avrà nel caso in cui la cartella bit non è già presente nella home, infatti:

bit3lux@bit3lux:~$ mkdir bit && cd bit
bit3lux@bit3lux:~/bit$

In questo secondo caso mkdir ha creato la directory bit, quindi il suo exit status è pari a zero; e, proprio perchè pari a zero (che significa che il comando mkdir ha avuto successo), l'operatore AND ha eseguito il comando cd.

Questo discorso, di carattere generale, sull'exit status l'ho voluto fare proprio per toccare con mani come "ragiona" la shell. 

Ricapitoliamo.

  1. Ogni comando restituisce un exit status 
  2. Un comando che ha avuto successo restituisce un exit status pari a 0
  3. In caso di insuccesso, viene restituito un valore diverso da zero.
  4. Il codice di uscita è un numero compreso tra 0 e 255
  5. Anche uno script può terminare col comando exit (che sta per exit status appunto)
  6. Per vedere il valore di ritorno di un comando eseguito, basta scrivere echo $? e premere invio

ritorniamo all'esempio fatto sopra:

$ mkdir bit && cd bit

Abbiamo detto che, se la cartella "bit" è già presente nella home, avremo:

bit3lux@bit3lux:~$ mkdir bit && cd bit
mkdir: impossibile creare la directory "bit": Il file esiste

se ora digitiamo
$ echo $?

Il valore di ritorno sarà pari a 1, che significa che l'ultimo comando (cd bit) non ha avuto successo.

Poniamo adesso che la cartella "bit" non sia presente nella home

bit3lux@bit3lux:~$ mkdir bit && cd bit
bit3lux@bit3lux:~/bit$ echo $?
0

Come potete vedere, il valore di ritorno sarà pari a zero. Ciò significa che l'ultimo comando eseguito (cd bit) ha avuto successo.

Ora, e solo ora, possiamo trattare della differenza tra [ e [[, ma nel prossimo post teorico!

Lightuono, nel suo prossimo post pratico, ci parlerà dell'exit status in modo più approfondito e con svariati esempi!

Ciao :)

Io e Lightuono

Nessun commento:

Posta un commento