Tracce
/
Bash
Bash
/
Programma
/
Condizionali
Co

Condizionali in Bash

{one: "1 esercizio", many: "%{count} esercizi", other: "%{count} esercizi"}

Informazioni su Condizionali

Verità in Bash

Bash non ha il concetto di valori booleani. Ci sono stringhe e numeri, e array di stringhe o di numeri. Quindi come fanno i comandi condizionali a gestire vero e falso?

Lo stato di uscita

I comandi producono uno stato di uscita quando terminano. Lo stato di uscita è un numero intero compreso tra 0 e 255 inclusi. Bash considera uno stato di uscita zero come successo. Qualsiasi altro stato di uscita rappresenta un fallimento.

Questo vale per tutti i comandi, compresi i comandi integrati di bash, le parole chiave e le funzioni.

Il comando "if"

La sintassi di base del comando if è

if CONDITIONAL_COMMANDS; then TRUE_COMMANDS; else FALSE_COMMANDS; fi

Inizia con if; i comandi della condizione sono separati dai comandi «di successo» da then; e termina con fi. La clausola else è facoltativa.

CONDITIONAL_COMMANDS può essere un singolo comando oppure una lista di comandi.

I CONDITIONAL_COMMANDS vengono eseguiti e

  • se lo stato di uscita è zero (successo), vengono eseguiti i TRUE_COMMANDS.
  • se lo stato di uscita è diverso da zero (fallimento), vengono eseguiti i FALSE_COMMANDS, se sono presenti.

Si possono creare rami a cascata con elif

if CONDITIONAL_COMMANDS
then TRUE_COMMANDS
elif CONDITIONAL_COMMANDS_2
then TRUE_COMMANDS_2
# more elif branches ...
else FALSE_COMMANDS
fi

Deve esserci un punto e virgola o un a capo prima delle parole then, elif, else e fi.

Per sottolineare il punto: è lo stato di uscita dei comandi condizionali a controllare il flusso. Per esempio, grep restituisce 0 se trova una corrispondenza e 1 se non la trova. L'opzione -q sopprime l'output e produce solo lo stato di uscita.

if grep -q "my pattern" my_file; then echo "the pattern is found in the file"; fi

I comandi "[" e "test"

Non c'è nessuna sintassi speciale attorno ai CONDITIONAL_COMMANDS. Probabilmente sei abituato a vedere istruzioni if come questa:

if [ "$password" = "secure" ]; then
    echo "Welcome!"
fi

[ non è una sintassi speciale. È un comando che valuta l'espressione condizionale ed esce con uno stato di successo o di fallimento. Come per tutti i comandi, lo spazio tra esso e i suoi argomenti è obbligatorio.

In realtà [ è un sinonimo del comando test. Sono esattamente la stessa cosa, tranne per il fatto che l'ultimo argomento di [ deve essere ].

Espressioni condizionali

Tra [ e ] scrivi un'espressione condizionale. Alcune espressioni condizionali tipiche sono:

[ -f "$filename" ]             # file operations
[ "$string1" = "$string2" ]    # string comparisons
[ "$num1" -eq "$num2" ]        # arithmetic comparisons

Ci sono molte altre operazioni disponibili; sono elencate nella sezione Bash Conditional Expressions del manuale.

Note

Negli esempi qui sopra, nota che tutte le variabili sono racchiuse tra virgolette. I comandi test e [ sono comandi normali, in cui gli argomenti sono soggetti alla suddivisione delle parole e all'espansione dei nomi di file come in qualsiasi altro comando.

Vale la pena sottolinearlo perché le espressioni condizionali vengono valutate in modo diverso a seconda di quanti argomenti fornisci:

  • 0 argomenti: lo stato di uscita è diverso da zero (fallimento)
  • 1 argomento: lo stato di uscita è zero (successo) se l'argomento non è vuoto, diverso da zero se è vuoto.
  • 2 argomenti: il primo argomento deve essere un operatore unario (come [ -z "$name" ]), oppure un ! (che nega lo stato del test con 1 argomento)
  • e altro.

Puoi ottenere risultati inattesi se ti dimentichi di usare le virgolette:

str=""

# this prints "empty"
if [ -n "$str" ]; then echo "not empty"; else echo "empty"; fi

# leaving the variable unquoted results in incorrect "not empty" output
if [ -n $str ]; then echo "not empty"; else echo "empty"; fi

La parola chiave "[["

Il [[...]] costrutto condizionale non è un comando, ma una parola chiave. Questo significa che, anche se viene gestito come qualsiasi altro comando, ha regole di analisi sintattica speciali. La particolarità di [[ è che le variabili espanse al suo interno non sono soggette alla suddivisione delle parole né all'espansione dei nomi di file. Di conseguenza il comando si comporta come ti aspetti, anche senza virgolette.

if [[ -n $str ]]; then echo "not empty"; else echo "empty"; fi

[[ supporta tutte le espressioni condizionali che test e [ sono in grado di gestire. Inoltre, [[ offre

  • l'operatore =~ per la corrispondenza con espressioni regolari,
  • == e != che funzionano come operatori di corrispondenza con pattern glob,
  • && e || come operatori logici (regola di analisi speciale),
  • < e > come operatori di confronto tra stringhe «nudi» (regola di analisi speciale: dato che sono simboli di redirezione, in [ devono essere preceduti da una barra rovesciata).

È opinione diffusa che queste funzionalità speciali offrano così tanti vantaggi che [[ dovrebbe essere usato in modo esclusivo. (Per esempio, la Google Shell Style Guide.)

Il comando "case"

case è un altro comando di controllo del flusso. È simile a un'istruzione «switch» di altri linguaggi.

case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac

La WORD viene confrontata con ciascun PATTERN. Quando uno corrisponde, vengono eseguiti i COMMANDS.

read -p "Guess the secret word: " word
case "$word" in
    secret) echo "Yes, you guessed it!" ;;
    ??????) echo "That's the right number of letters." ;;
    s*)     echo "You guessed the first letter." ;;
    *)      echo "Not even close! Try again." ;;
esac

Ogni clausola COMMANDS deve terminare con due punti e virgola, ;;.

Note
  1. Esistono alternative che offrono la funzionalità di esecuzione in cascata dei comandi e di prosecuzione della corrispondenza dei pattern. Per i dettagli, consulta il manuale.
  2. Ricorda che abbiamo parlato dei pattern nella sezione Espansione dei nomi di file del concetto Quoting.
Modifica tramite GitHub Il collegamento si apre in una nuova finestra o scheda