Szukaj…


Składnia

  • Zdefiniuj funkcję za pomocą słowa kluczowego function :

    function f {
    

    }

  • Zdefiniuj funkcję za pomocą () :

    f(){
    

    }

  • Zdefiniuj funkcję za pomocą słowa kluczowego function i () :

    function f(){
    

    }

Prosta funkcja

W helloWorld.sh

#!/bin/bash

# Define a function greet
greet ()
{
    echo "Hello World!"
}

# Call the function greet
greet

Podczas uruchamiania skryptu widzimy naszą wiadomość

$ bash helloWorld.sh
Hello World!

Zauważ, że pozyskanie pliku z funkcjami powoduje, że są one dostępne w bieżącej sesji bash.

$ source helloWorld.sh   # or, more portably, ". helloWorld.sh"
$ greet
Hello World!

Możesz export funkcję w niektórych powłokach, aby była narażona na procesy potomne.

bash -c 'greet'  # fails
export -f greet  # export function; note -f
bash -c 'greet'  # success

Funkcje z argumentami

W helloJohn.sh :

#!/bin/bash

greet() {
  local name="$1"
  echo "Hello, $name"
}

greet "John Doe"
# running above script
$ bash helloJohn.sh
Hello, John Doe
  1. Jeśli nie zmodyfikujesz argumentu w żaden sposób, nie ma potrzeby kopiowania go do zmiennej local - po prostu echo "Hello, $1" .

  2. Możesz użyć $1 $2 $3 itd., Aby uzyskać dostęp do argumentów wewnątrz funkcji.

    Uwaga: dla argumentów powyżej 9 $10 nie zadziała (bash przeczyta to jako 1 0 $ ), musisz zrobić ${10} , ${11} i tak dalej.

  3. $@ odnosi się do wszystkich argumentów funkcji:

    #!/bin/bash
    foo() {
      echo "$@"
    }
    
    foo 1 2 3 # output => 1 2 3
    

    Uwaga: praktycznie zawsze powinieneś używać podwójnych cudzysłowów wokół "$@" , tak jak tutaj.

    Pominięcie cudzysłowów spowoduje, że powłoka rozwinie symbole wieloznaczne (nawet jeśli użytkownik specjalnie je zacytował, aby tego uniknąć) i ogólnie wprowadzi niepożądane zachowanie, a potencjalnie nawet problemy z bezpieczeństwem.

    foo "string with spaces;" '$HOME' "*"
    # output => string with spaces; $HOME *
    
  4. dla domyślnych argumentów użyj ${1:-default_val} . Na przykład:

    #!/bin/bash
    foo() {
      local val=${1:-25}
      echo "$val"
    }
    
    foo     # output => 25
    foo 30  # output => 30
    
  5. aby zażądać argumentu użyj ${var:?error message}

    foo() {
      local val=${1:?Must provide an argument}
      echo "$val"
    }
    

Zwraca wartość z funkcji

Instrukcja return w Bash nie zwraca wartości takiej jak funkcje C. Zamiast tego wychodzi z funkcji ze statusem return. Możesz myśleć o tym jako o statusie wyjścia tej funkcji.

Jeśli chcesz zwrócić wartość z funkcji, wyślij ją na standardowe stdout następujący sposób:

fun() {
    local var="Sample value to be returned"
    echo "$var"
    #printf "%s\n" "$var"
}

Teraz, jeśli to zrobisz:

var="$(fun)"

wyjście fun będzie przechowywane w $var .

Obsługa flag i parametrów opcjonalnych

Wbudowane getopts mogą być używane wewnątrz funkcji do pisania funkcji, które przyjmują flagi i parametry opcjonalne. Nie stanowi to żadnej szczególnej trudności, ale trzeba odpowiednio poradzić sobie z wartościami dotykanymi przez getopts . Jako przykład definiujemy funkcję failwith, która zapisuje komunikat na stderr i wychodzi z kodem 1 lub dowolnym kodem podanym jako parametr do opcji -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}"
}

Z tej funkcji można korzystać w następujący sposób:

failwith '%s: File not found.' "${filename}"
failwith -x 70 'General internal error.'

i tak dalej.

Zauważ, że tak jak w przypadku printf , zmienne nie powinny być używane jako pierwszy argument. Jeśli komunikat do wydrukowania składa się z zawartości zmiennej, należy użyć specyfikatora %s aby ją wydrukować, jak w

failwith '%s' "${message}"

Kod wyjścia funkcji jest kodem wyjścia jej ostatniego polecenia

Rozważ tę przykładową funkcję, aby sprawdzić, czy host działa:

is_alive() {
    ping -c1 "$1" &> /dev/null
}

Ta funkcja wysyła pojedynczy ping do hosta określonego przez pierwszy parametr funkcji. Wyjście i wyjście błędu ping są przekierowywane do /dev/null , więc funkcja nigdy niczego nie wypisze. Ale polecenie ping będzie miało kod zakończenia 0 w przypadku powodzenia i niezerowe w przypadku niepowodzenia. Ponieważ jest to ostatnia (aw tym przykładzie jedyna) komenda funkcji, kod wyjścia ping będzie ponownie użyty dla kodu wyjścia samej funkcji.

Ten fakt jest bardzo przydatny w instrukcjach warunkowych.

Na przykład, jeśli host graucho jest graucho , połącz się z nim za pomocą ssh :

if is_alive graucho; then
    ssh graucho
fi

Kolejny przykład: wielokrotnie sprawdzaj, aż host graucho jest uruchomiony, a następnie połącz się z nim za pomocą ssh :

while ! is_alive graucho; do
    sleep 5
done
ssh graucho

Wydrukuj definicję funkcji

getfunc() {
    declare -f "$@"
}

function func(){
    echo "I am a sample function"
}

funcd="$(getfunc func)" 
getfunc func # or echo "$funcd"

Wynik:

func () 
{ 
    echo "I am a sample function"
}

Funkcja akceptująca parametry nazwane

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"
}

Przykładowe użycie:

foo -f
foo -t 10
foo -f --tail 10
foo --follow --tail 10


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow