Ricerca…
Sintassi
Definire una funzione con la parola chiave
function
:function f {
}
Definire una funzione con
()
:f(){
}
Definire una funzione sia con la parola chiave
function
sia con()
:function f(){
}
Funzione semplice
In helloWorld.sh
#!/bin/bash
# Define a function greet
greet ()
{
echo "Hello World!"
}
# Call the function greet
greet
Nel gestire la sceneggiatura, vediamo il nostro messaggio
$ bash helloWorld.sh
Hello World!
Si noti che l' acquisizione di un file con funzioni li rende disponibili nella sessione di bash corrente.
$ source helloWorld.sh # or, more portably, ". helloWorld.sh"
$ greet
Hello World!
È possibile export
una funzione in alcune shell, in modo che sia esposta ai processi figli.
bash -c 'greet' # fails
export -f greet # export function; note -f
bash -c 'greet' # success
Funziona con argomenti
In helloJohn.sh
:
#!/bin/bash
greet() {
local name="$1"
echo "Hello, $name"
}
greet "John Doe"
# running above script
$ bash helloJohn.sh
Hello, John Doe
Se non si modifica l'argomento in alcun modo, non è necessario copiarlo su una variabile
local
- semplicementeecho "Hello, $1"
.Puoi usare
$1
,$2
,$3
e così via per accedere agli argomenti all'interno della funzione.Nota: per argomenti più di 9
$10
non funzioneranno (bash lo leggerà come $ 1 0), devi fare${10}
,${11}
e così via.$@
riferisce a tutti gli argomenti di una funzione:#!/bin/bash foo() { echo "$@" } foo 1 2 3 # output => 1 2 3
Nota: dovresti praticamente sempre usare le virgolette doppie intorno a
"$@"
, come qui.Omettendo le virgolette, la shell espanderà i caratteri jolly (anche quando l'utente li ha espressamente citati per evitarlo) e in genere introdurrà comportamenti indesiderati e potenzialmente problemi di sicurezza.
foo "string with spaces;" '$HOME' "*" # output => string with spaces; $HOME *
per gli argomenti predefiniti usa
${1:-default_val}
. Per esempio:#!/bin/bash foo() { local val=${1:-25} echo "$val" } foo # output => 25 foo 30 # output => 30
per richiedere un argomento usa
${var:?error message}
foo() { local val=${1:?Must provide an argument} echo "$val" }
Valore di ritorno da una funzione
L'istruzione return
in Bash non restituisce un valore come C-functions, ma esce dalla funzione con uno stato di ritorno. Puoi considerarlo come lo stato di uscita di quella funzione.
Se si desidera restituire un valore dalla funzione, quindi inviare il valore a stdout
questo modo:
fun() {
local var="Sample value to be returned"
echo "$var"
#printf "%s\n" "$var"
}
Ora, se lo fai:
var="$(fun)"
l'output di fun
verrà archiviato in $var
.
Gestione flag e parametri opzionali
I getopts incorporati possono essere utilizzati all'interno di funzioni per scrivere funzioni che supportano flag e parametri opzionali. Questo non presenta difficoltà particolari, ma bisogna gestire in modo appropriato i valori toccati da getopts . Ad esempio, definiamo una funzione failwith che scrive un messaggio su stderr ed esce con il codice 1 o un codice arbitrario fornito come parametro per l'opzione -x
:
# failwith [-x STATUS] PRINTF-LIKE-ARGV
# Fail with the given diagnostic message
#
# The -x flag can be used to convey a custom exit status, instead of
# the value 1. A newline is automatically added to the output.
failwith()
{
local OPTIND OPTION OPTARG status
status=1
OPTIND=1
while getopts 'x:' OPTION; do
case ${OPTION} in
x) status="${OPTARG}";;
*) 1>&2 printf 'failwith: %s: Unsupported option.\n' "${OPTION}";;
esac
done
shift $(( OPTIND - 1 ))
{
printf 'Failure: '
printf "$@"
printf '\n'
} 1>&2
exit "${status}"
}
Questa funzione può essere utilizzata come segue:
failwith '%s: File not found.' "${filename}"
failwith -x 70 'General internal error.'
e così via.
Nota che per quanto riguarda printf , le variabili non dovrebbero essere usate come primo argomento. Se il messaggio da stampare consiste nel contenuto di una variabile, si dovrebbe usare l' %s
per stamparlo, come in
failwith '%s' "${message}"
Il codice di uscita di una funzione è il codice di uscita del suo ultimo comando
Considera questa funzione di esempio per verificare se un host è attivo:
is_alive() {
ping -c1 "$1" &> /dev/null
}
Questa funzione invia un singolo ping all'host specificato dal primo parametro di funzione. L'output e l'output di errore di ping
sono entrambi reindirizzati a /dev/null
, quindi la funzione non emetterà mai nulla. Ma il comando ping
avrà il codice di uscita 0 in caso di successo e non zero in caso di errore. Poiché questo è l'ultimo (e in questo esempio, l'unico) comando della funzione, il codice di uscita del ping
verrà riutilizzato per il codice di uscita della funzione stessa.
Questo fatto è molto utile nelle dichiarazioni condizionali.
Ad esempio, se l'host graucho
è graucho
, quindi connettersi ad esso con ssh
:
if is_alive graucho; then
ssh graucho
fi
Un altro esempio: controlla ripetutamente fino a quando host graucho
è graucho
, quindi connettiti ad esso con ssh
:
while ! is_alive graucho; do
sleep 5
done
ssh graucho
Stampa la definizione della funzione
getfunc() {
declare -f "$@"
}
function func(){
echo "I am a sample function"
}
funcd="$(getfunc func)"
getfunc func # or echo "$funcd"
Produzione:
func ()
{
echo "I am a sample function"
}
Una funzione che accetta parametri con nome
foo() {
while [[ "$#" -gt 0 ]]
do
case $1 in
-f|--follow)
local FOLLOW="following"
;;
-t|--tail)
local TAIL="tail=$2"
;;
esac
shift
done
echo "FOLLOW: $FOLLOW"
echo "TAIL: $TAIL"
}
Esempio di utilizzo:
foo -f
foo -t 10
foo -f --tail 10
foo --follow --tail 10