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
Jeśli nie zmodyfikujesz argumentu w żaden sposób, nie ma potrzeby kopiowania go do zmiennej
local
- po prostuecho "Hello, $1"
.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.$@
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 *
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
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