Introduzione

Il processo decisionale è uno dei concetti fondamentali della programmazione informatica. Come in qualsiasi altro linguaggio di programmazione, if, if..else, if..elif..else e dichiarazioni if nidificate in Bash possono essere utilizzati per eseguire codice in base a una certa condizione.

In questo tutorial, ti guideremo attraverso le basi delle istruzioni if di Bash e ti mostreremo come usarle negli script della shell.

Dichiarazione if

I condizionali if di Bash possono avere forme diverse. La dichiarazione if di base assume la seguente forma:

if TEST-COMMAND
then
  STATEMENTS
fi

L'istruzione if inizia con la parola if chiave seguita dall'espressione condizionale e dalla parola chiave then. L'istruzione termina con la parola chiave fi.

Se TEST-COMMAND viene valutato True, viene eseguito STATEMENTS. Se TEST-COMMAND ritorna False, non succede nulla, STATEMENTS viene ignorato.

In generale, è buona norma inserire nuovamente il codice e separare i blocchi di codice con righe vuote. La maggior parte delle persone sceglie di utilizzare l'indentation (rientro) a 4 o 2 spazi. Indentation e righe vuote rendono il tuo codice più leggibile e organizzato.

Diamo un'occhiata al seguente script di esempio che controlla se un determinato numero è maggiore di 10.

#!/bin/bash

echo -n "Enter a number: "
read VAR

if [[ $VAR -gt 10 ]]
then
  echo "The variable is greater than 10."
fi

Salvare il codice in un file ed eseguirlo dalla riga di comando:

bash test.sh

Lo script ti chiederà di inserire un numero. Se, ad esempio, si immette 15, il comando  test valuterà true perché 15 è maggiore di 10 e verrà eseguito il comando  echo all'interno della clausola then .

The variable is greater than 10.

Dichiarazione if else

L'istruzione Bash if..else ha la forma seguente:

if TEST-COMMAND
then
  STATEMENTS1
else
  STATEMENTS2
fi

Se TEST-COMMAND viene valutato True, verrà eseguito STATEMENTS1 . Altrimenti, se TEST-COMMAND ritorna False, STATEMENTS2 verrà eseguito. È possibile avere una sola clausola else nell'istruzione.

Aggiungiamo una clausola else al precedente script di esempio:

#!/bin/bash

echo -n "Enter a number: "
read VAR

if [[ $VAR -gt 10 ]]
then
  echo "The variable is greater than 10."
else
  echo "The variable is equal or less than 10."
fi

Se si esegue il codice e si immette un numero, lo script stamperà un messaggio diverso a seconda che il numero sia maggiore o minore/uguale a 10.

Dichiarazione if elif else

L'istruzione Bash  if..elif..else ha la forma seguente:

if TEST-COMMAND1
then
  STATEMENTS1
elif TEST-COMMAND2
then
  STATEMENTS2
else
  STATEMENTS3
fi

Se TEST-COMMAND1 viene valutato True, STATEMENTS1 verrà eseguito. Se TEST-COMMAND2 viene valutato True, STATEMENTS2 verrà eseguito. Se nessuno dei comandi di test viene valutato True, STATEMENTS2 viene eseguito.

È possibile avere una o più clausole elif nell'istruzione. La clausola else è facoltativa.

Le condizioni sono valutate in sequenza. Quando una condizione ritorna, True le condizioni rimanenti non vengono eseguite e il controllo del programma passa alla fine delle istruzioni if.

Aggiungiamo una clausola elif allo script precedente:

#!/bin/bash

echo -n "Enter a number: "
read VAR

if [[ $VAR -gt 10 ]]
then
  echo "The variable is greater than 10."
elif [[ $VAR -eq 10 ]]
then
  echo "The variable is equal to 10."
else
  echo "The variable is less than 10."
fi

Dichiarazioni nidificate if

Bash consente di nidificare le istruzioni if all'interno delle istruzioni if. È possibile inserire più istruzioni if all'interno di un'altra istruzione if.

Il seguente script ti chiederà di inserire tre numeri e stamperà il numero più grande tra i tre numeri.

#!/bin/bash

echo -n "Enter the first number: "
read VAR1
echo -n "Enter the second number: "
read VAR2
echo -n "Enter the third number: "
read VAR3

if [[ $VAR1 -ge $VAR2 ]]
then
  if [[ $VAR1 -ge $VAR3 ]]
  then
    echo "$VAR1 is the largest number."
  else
    echo "$VAR3 is the largest number."
  fi
else
  if [[ $VAR2 -ge $VAR3 ]]
  then
    echo "$VAR2 is the largest number."
  else
    echo "$VAR3 is the largest number."
  fi
fi

Ecco come apparirà l'output:

Enter the first number: 4
Enter the second number: 7
Enter the third number: 2
7 is the largest number.

Invece di utilizzare le istruzioni if nidificate , in genere è più efficiente utilizzare l'istruzione case.

Condizioni multiple

La logica degli operatori OR e AND consentono di utilizzare più condizioni nelle istruzioni if.

Ecco un'altra versione dello script per stampare il numero più grande tra i tre numeri. In questa versione, anziché avere le istruzioni nidificate if, utilizzeremo l'operatore logic AND (&&).

#!/bin/bash

echo -n "Enter the first number: "
read VAR1
echo -n "Enter the second number: "
read VAR2
echo -n "Enter the third number: "
read VAR3

if [[ $VAR1 -ge $VAR2 ]] && [[ $VAR1 -ge $VAR3 ]]
then
  echo "$VAR1 is the largest number."
elif [[ $VAR2 -ge $VAR1 ]] && [[ $VAR2 -ge $VAR3 ]]
then
  echo "$VAR2 is the largest number."
else
  echo "$VAR3 is the largest number."
fi

Operatori di test

In Bash, il comando test utilizza una delle seguenti forme di sintassi:

test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]

Se vuoi che il tuo script sia portatile, dovresti preferire usare il vecchio comando [ test che è disponibile su tutte le shell POSIX. La nuova versione aggiornata del comando test [[ (doppie parentesi) è supportata sulla maggior parte dei sistemi moderni che utilizzano Bash, Zsh e Ksh come shell predefinita.

Per negare l'espressione di test utilizzare l'operatore logic NOT (!). Quando si confrontano le stringhe, utilizzare sempre virgolette singole o doppie per evitare problemi di divisione delle parole o globbing.

Di seguito sono riportati alcuni degli operatori più comunemente usati:

  • -n VAR - Vero se la lunghezza di VAR è maggiore di zero.
  • -z VAR  - Vero se il VAR è vuoto.
  • STRING1 = STRING2 - True [STRING1 e STRING2 sono uguali.
  • STRING1 != STRING2 - True STRING1 e STRING2 non sono uguali.
  • INTEGER1 -eq INTEGER2 - True INTEGER1 e INTEGER2 sono uguali.
  • INTEGER1 -gt INTEGER2 - True INTEGER1 è maggiore di INTEGER2.
  • INTEGER1 -lt INTEGER2 - True INTEGER1 è inferiore a INTEGER2.
  • INTEGER1 -ge INTEGER2 - True INTEGER1 è uguale o maggiore di INTEGER2.
  • INTEGER1 -le INTEGER2 - True INTEGER1 è uguale o inferiore a INTEGER2.
  • -h`FILE` - Vero se il FILE esiste ed è un collegamento simbolico.
  • -r`FILE` - Vero se il FILE esiste ed è leggibile.
  • -w`FILE` - Vero se il FILE esiste ed è scrivibile.
  • -x`FILE` - Vero se il FILE esiste ed è eseguibile.
  • -d`FILE` - Vero se il FILE esiste ed è una directory.
  • -e`FILE` - Vero se il FILE esiste ed è un file, indipendentemente dal tipo (nodo, directory, socket, ecc.).
  • -f`FILE` - Vero se il FILE esiste ed è un file normale (non una directory o un dispositivo).

Conclusione

Le dichiarazioni if, if..else e if..elif..else consentono di controllare il flusso di esecuzione di Bash valutando determinate condizioni.