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
  1. Se non si modifica l'argomento in alcun modo, non è necessario copiarlo su una variabile local - semplicemente echo "Hello, $1" .

  2. 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.

  3. $@ 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 *
    
  4. 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
    
  5. 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


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow