Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Funzioni

Imparare a dichiarare ed utilizzare le funzioni all'interno degli script di Shell su Linux con Bash.
Imparare a dichiarare ed utilizzare le funzioni all'interno degli script di Shell su Linux con Bash.
Link copiato negli appunti

Una funzione è uno speciale tipo di variabile che possiamo immaginare come uno script contenuto in un altro script. Questo permette di raggruppare una sequenza di comandi all'interno di un singolo comando, il che risulta particolarmente utile se tale sequenza deve essere eseguita più volte in diverse parti dello script.

A differenza dei linguaggi di programmazione tradizionali, in cui è comunemente possibile distinguere tra funzioni - che ritornano un singolo valore e non producono nessun output - e procedure - che non ritornano alcun valore ma possono produrre un output - una funzione in Bash può ascriversi ad entrambi questi comportamenti. Una funziona è infatti in grado di cambiare lo stato di una o più variabili, utilizzare il comando exit per interrompere l'esecuzione dello script, usare il comando return per terminare la funzione e ritornare il valore fornito alla porzione di codice chiamante, ed infine stampare un output tramite il comando echo.

Vediamo un semplice esempio:

aggiungi_utente()
{
  ID=$1
  NOME=$2
  COGNOME=$3
  echo "Aggiunto l'utente $ID ($NOME $COGNOME)"
}
echo "Inizio dello script..."
aggiungi_utente 0 Albert Einstein
aggiungi_utente 1 Stephen Hawking
aggiungi_utente 2 Alan Turing
echo "Fine dello script..."

La seconda linea rappresenta una dichiarazione di funzione, terminando in (), ed essendo seguita da {. Da qui, tutto ciò che precede il simbolo } è considerato parte della funzione. Ciò significa che tale codice non viene eseguito dall'interprete Bash, se non quando la funzione viene chiamata.

Fino ad ora ci siamo abituati al fatto che uno script fosse eseguito sequenzialmente, ma questo non è più valido nel caso in cui si utilizzino le funzioni. Nell'esempio precedente, la funzione aggiungi_utente viene letta e ne viene controllata la sintassi, ma i comandi in essa contenuti non saranno eseguiti finché la funzione stessa non venga richiamata.

L'esecuzione dello script precedente inizia con il comando echo "Inizio dello script..."; la linea successiva, aggiungi_utente 0 Albert Einstein, rappresenta una chiamata della funzione aggiungi_utente, che viene eseguita in un ambiente dove $1 vale 0, $2 vale Albert e $3 vale Einstein. Perciò, a prescindere dal valore di $1 al di fuori della funzione, al suo interno il valore sarà 0. Se si volesse fare riferimento al valore originario di $1 all'interno della funzione, dovremo assegnargli un nome - come A=$1 - prima di richiamare la funzione; così, all'interno della funzione, potremo riferirci a $A. Una volta terminata l'esecuzione del corpo della funzione, il controllo ritorna alla linea successiva del codice principale, aggiungi_utente 1 Stephen Hawking.

Visibilità delle variabili e subshell

A differenza dei più comuni linguaggi di programmazione, lo scope delle variabili in Bash è pressoché inesistente, tranne che per i parametri ($1, $2, $@, ecc.); lo scope di una variabile determina la parte del programma in cui tale variabile è visibile. Consideriamo un semplice esempio:

funzione()
{
  echo "I parametri della funzione sono: $@"
  x=2
}
echo "I parametri dello script sono: $@"
x=1
echo "x è $x"
funzione 1 2 3
echo "x è $x"

Richiamando lo script precedente coi parametri a b c si ottiene il seguente risultato:

I parametri dello script sono: a b c
x è 1
I parametri della funzione sono: 1 2 3
x è 2

La variabile $@ contenente i parametri viene modificata all'interno della funzione per riflettere il modo in cui essa è stata richiamata. La variabile x invece è a tutti gli effetti una variabile globale: la funzione ne altera il valore e questa modifica rimane effettiva anche quando il controllo ritorna allo script principale.

Le uniche eccezioni a quanto detto finora sullo scope delle variabili valgono per le subshell e il comando built-in local. In Bash, uno o più comandi racchiusi da parentesi vengono eseguiti in una subshell; questa riceve una copia dell'ambiente di esecuzione, che include - fra le altre cose - tutte le variabili dichiarate. Ogni modifica effettuata all'ambiente di esecuzione dalla subshell non ha però effetto sulla shell principale una volta completata l'esecuzione della subshell. Questo vale anche per le funzioni: una funzione dichiarata in una subshell non è visibile all'esterno di essa. Usando invece la sintassi local var o local var=val si restringe lo scope della variabile var a ogni diversa chiamata della funzione in cui viene dichiarata; in effetti, utilizzare local equivale ad inserire la chiamata di funzione in una subshell, ma solo per una singola variabile. L'unica differenza fra queste due tecniche è che laddove una subshell copia il valore delle proprie variabili dalla shell nella quale viene creata, un comando come local var nasconde immediatamente il valore precedente di val, cioè la variabile diventa localmente non inizializzata. Se abbiamo bisogno di inizializzare la variabile con il suo valore esistente, è necessario farlo esplicitamente, utilizzando local var="$var".

Valori di ritorno

Nello stesso modo in cui veniva utilizzato il valore di ritorno del comando test, è possibile sfruttare il comando return per ritornare un valore specifico da una funzione allo script principale che ne ha effettuato la chiamata. Di seguito vediamo come è possibile modificare facilmente il primo script che abbiamo introdotto sfruttando il valore di ritorno di una funzione.

aggiungi_utente()
{
  ((ID++))
  return $ID
}
ID=0
echo "Inizio dello script..."
aggiungi_utente Albert Einstein
echo "Aggiunto l'utente $? (Albert Einstein)"
aggiungi_utente Stephen Hawking
echo "Aggiunto l'utente $? (Stephen Hawking)"
aggiungi_utente Alan Turing
echo "Aggiunto l'utente $? (Alan Turing)"
echo "Fine dello script..."

Ti consigliamo anche