Quando i tuoi script bash diventano sempre più grandi, le cose possono diventare molto disordinate!
Potresti ritrovarti a riscrivere gli stessi pezzi di codice ancora e ancora in parti diverse dei tuoi script bash.
Fortunatamente, puoi evitare di riscrivere il codice utilizzando le funzioni in bash che renderanno i tuoi script più organizzati e leggibili.
In questo tutorial imparerai a creare funzioni, restituire valori di funzione e passare argomenti di funzione negli script della shell bash.
Inoltre, imparerai come funziona l'ambito delle variabili e come definire funzioni ricorsive.
Creazione di funzioni in bash
Esistono due diverse sintassi per dichiarare le funzioni bash. La seguente sintassi è il modo più comune utilizzato per creare funzioni bash:
function_name () {
commands
}
La seconda meno comunemente usata per creare funzioni bash inizia con la funzione di lavoro riservata seguita dal nome della funzione come segue:
function function_name {
commands
}
Ora ci sono un paio di cose di cui dovresti essere ben consapevole quando lavori con le funzioni:
- Una funzione non verrà mai eseguita/eseguita a meno che tu non invochi/chiama la funzione.
- La definizione della funzione deve precedere qualsiasi chiamata alla funzione.
Ogni volta che vuoi che una funzione venga eseguita, devi solo chiamarla! Una chiamata di funzione viene eseguita semplicemente facendo riferimento al nome della funzione.
Dai un'occhiata al seguente fun.sh script bash:
#!/bin/bash
hello () {
echo "Hello World"
}
hello
hello
hello
Ho definito una funzione denominata ciao che semplicemente fa eco alla frase "Hello World" al terminale. Nota che ho fatto tre ciao chiamate di funzione e quindi se esegui lo script, vedrai il "Hello World" riga stampata tre volte sullo schermo:
[email protected]:~$ ./fun.sh
Hello World
Hello World
Hello World
Restituzione dei valori delle funzioni in bash
In molti linguaggi di programmazione, le funzioni restituiscono un valore quando vengono chiamate; tuttavia, questo non è il caso di bash poiché le funzioni bash non restituiscono valori.
Quando una funzione bash termina l'esecuzione, restituisce lo stato di uscita dell'ultimo comando eseguito catturato in $? variabile. Zero indica un'esecuzione riuscita o un numero intero positivo diverso da zero (1-255) per indicare un errore.
Puoi utilizzare un ritorno istruzione per modificare lo stato di uscita della funzione. Ad esempio, dai un'occhiata al seguente error.sh sceneggiatura:
#! /bin/bash
error () {
blabla
return 0
}
error
echo "The return status of the error function is: $?"
Se esegui error.sh bash, potresti essere sorpreso dall'output:
[email protected]:~$ ./error.sh
./error.sh: line 4: blabla: command not found
The return status of the error function is: 0
Senza il ritorno 0 dichiarazione, l'errore la funzione non avrebbe mai restituito uno stato di uscita diverso da zero come blabla is risulta in un comando non trovato errore.
Quindi, come puoi vedere, anche se le funzioni bash non restituiscono valori, ho fatto una soluzione alternativa alterando gli stati di uscita delle funzioni.
Dovresti anche essere consapevole del fatto che un'istruzione return termina immediatamente una funzione.
Passaggio di argomenti alla funzione bash
Puoi passare argomenti a una funzione proprio come puoi passare argomenti a uno script bash. Includi semplicemente gli argomenti quando esegui la chiamata di funzione.
Per dimostrare, diamo un'occhiata al seguente iseven.sh script bash:
#!/bin/bash
iseven () {
if [ $(($1 % 2)) -eq 0 ]; then
echo "$1 is even."
else
echo "$1 is odd."
fi
}
iseven 3
iseven 4
iseven 20
iseven 111
Il iseven() la funzione verifica se un numero è pari o dispari. Ho eseguito quattro chiamate di funzione a iseven() . Per ogni chiamata di funzione, ho fornito un numero che è il primo aumento della funzione iseven() ed è referenziato da $1 variabile nella definizione della funzione.
Eseguiamo iseven.sh bash per assicurarsi che funzioni:
[email protected]:~$ ./iseven.sh
3 is odd.
4 is even.
20 is even.
111 is odd.
Dovresti anche essere ben consapevole che gli argomenti della funzione bash e gli argomenti dello script bash sono due cose diverse. Per contrastare la differenza, dai un'occhiata al seguente funarg.sh script bash:
#!/bin/bash
fun () {
echo "$1 is the first argument to fun()"
echo "$2 is the second argument to fun()"
}
echo "$1 is the first argument to the script."
echo "$2 is the second argument to the script."
fun Yes 7
Esegui lo script con un paio di argomenti e osserva il risultato:
[email protected]:~$ ./funarg.sh Cool Stuff
Cool is the first argument to the script.
Stuff is the second argument to the script.
Yes is the first argument to fun()7 is the second argument to fun()
Come puoi vedere, anche se hai usato le stesse variabili $1 e $2 per fare riferimento sia agli argomenti dello script che agli argomenti della funzione, producono risultati diversi quando vengono chiamati dall'interno di una funzione.
Variabili locali e globali nelle funzioni bash
Le variabili Bash possono avere un ambito globale o locale. Puoi accedere a una variabile globale ovunque in uno script bash indipendentemente dall'ambito. Al contrario, è possibile accedere a una variabile locale solo dall'interno della definizione della loro funzione.
Per dimostrare, dai un'occhiata al seguente scope.sh script bash:
#!/bin/bash
v1='A'
v2='B'
myfun() {
local v1='C'
v2='D'
echo "Inside myfun(): v1: $v1, v2: $v2"
}
echo "Before calling myfun(): v1: $v1, v2: $v2"
myfun
echo "After calling myfun(): v1: $v1, v2: $v2"
Per prima cosa ho definito due variabili globali v1 e v2 . Poi dentro myfun() definizione, ho usato il locale parola chiave per definire una variabile locale v1 e modificato la variabile globale v2. Nota che puoi usare lo stesso nome di variabile per variabili locali in diverse funzioni.
Ora eseguiamo lo script:
[email protected]:~$ ./scope.sh
Before calling myfun(): v1: A, v2: B
Inside myfun(): v1: C, v2: D
After calling myfun(): v1: A, v2: D
Dall'output dello script, puoi concludere quanto segue:
- Una variabile locale con lo stesso nome di una variabile globale avrà la precedenza sulle variabili globali all'interno del corpo di una funzione.
- Puoi modificare una variabile globale dall'interno di una funzione.
Funzioni ricorsive
Una funzione ricorsiva è una funzione che chiama se stessa! Le funzioni ricorsive sono utili quando si tenta di risolvere un problema di programmazione che può essere suddiviso in sottoproblemi più piccoli.
La funzione fattoriale è un classico esempio di funzione ricorsiva. Dai un'occhiata al seguente factorial.sh script bash:
#!/bin/bash
factorial () {
if [ $1 -le 1 ]; then
echo 1
else
last=$(factorial $(( $1 -1)))
echo $(( $1 * last ))
fi
}
echo -n "4! is: "
factorial 4
echo -n "5! is: "
factorial 5
echo -n "6! is: "
factorial 6
Qualsiasi funzione ricorsiva deve iniziare con un caso base che è necessariamente terminare la catena di chiamate di funzione ricorsive. Nel fattoriale() funzione, il caso base è definito come segue:
if [ $1 -le 1 ]; then
echo 1
Ora deriva il caso ricorsivo per la funzione fattoriale. Per calcolare il fattoriale di un numero n dove n è un numero positivo maggiore di uno, puoi moltiplicare n dal fattoriale di n-1 :
factorial(n) = n * factorial(n-1)
Usiamo l'equazione precedente per scrivere questo caso ricorsivo:
last=$(factorial $(( $1 -1)))
echo $(( $1 * last ))
Ora esegui lo script e assicurati di ottenere i risultati corretti:
[email protected]:~$ ./factorial.sh
4! is: 24
5! is: 120
6! is: 720
Come esercizio aggiuntivo, prova a scrivere una funzione ricorsiva per calcolare l'ennesimo numero di Fibonacci. Per prima cosa, prova a trovare il caso base e poi il caso ricorsivo; hai capito!
Hai bisogno di più esercizio? Scarica il PDF qui sotto ed esercitati con le funzioni negli script bash. Hai anche le soluzioni nello stesso PDF.
Bash Capitolo 9 Domande pratiche Problemi e la loro soluzione per mettere in pratica ciò che hai appena appreso in questo capitolo Bash-Capitolo-9-Domande pratiche-Linux-Handbook.pdf31 KB
Eccezionale! Il prossimo e ultimo capitolo di questa serie applicherà tutto ciò che hai imparato finora per scrivere script bash efficaci che automatizzano noiose attività amministrative.