Bash
funktioner
Sök…
Syntax
Definiera en funktion med
function
nyckelord:function f {
}
Definiera en funktion med
()
:f(){
}
Definiera en funktion med både
function
sökord och()
:function f(){
}
Enkel funktion
I helloWorld.sh
#!/bin/bash
# Define a function greet
greet ()
{
echo "Hello World!"
}
# Call the function greet
greet
När vi kör skriptet ser vi vårt meddelande
$ bash helloWorld.sh
Hello World!
Observera att sourcing av en fil med funktioner gör dem tillgängliga i din nuvarande bash-session.
$ source helloWorld.sh # or, more portably, ". helloWorld.sh"
$ greet
Hello World!
Du kan export
en funktion i vissa skal så att den utsätts för barnprocesser.
bash -c 'greet' # fails
export -f greet # export function; note -f
bash -c 'greet' # success
Funktioner med argument
I helloJohn.sh
:
#!/bin/bash
greet() {
local name="$1"
echo "Hello, $name"
}
greet "John Doe"
# running above script
$ bash helloJohn.sh
Hello, John Doe
Om du inte ändrar argumentet på något sätt, finns det inget behov av att kopiera det till en
local
variabel - helt enkeltecho "Hello, $1"
.Du kan använda
$1
,$2
,$3
och så vidare för att komma åt argumenten i funktionen.Obs: för argument mer än 9
$10
fungerar inte (bash kommer att läsa det som $ 1 0), måste du göra${10}
,${11}
och så vidare.$@
hänvisar till alla argument för en funktion:#!/bin/bash foo() { echo "$@" } foo 1 2 3 # output => 1 2 3
Obs: Du bör praktiskt taget alltid använda dubbla citat runt
"$@"
, som här.Utelämnande av offerten kommer att få skalet att expandera jokertecken (även när användaren specifikt citerade dem för att undvika det) och generellt introducerar oönskat beteende och potentiellt till och med säkerhetsproblem.
foo "string with spaces;" '$HOME' "*" # output => string with spaces; $HOME *
för standardargument använder du
${1:-default_val}
. T.ex:#!/bin/bash foo() { local val=${1:-25} echo "$val" } foo # output => 25 foo 30 # output => 30
för att kräva ett argument använder du
${var:?error message}
foo() { local val=${1:?Must provide an argument} echo "$val" }
Returnera värde från en funktion
Den return
uttalande Bash inte returnera ett värde som C-funktioner, istället lämnar funktionen med en avkastning status. Du kan tänka på det som utgångsstatus för den funktionen.
Om du vill returnera ett värde från funktionen skickar du värdet till stdout
så här:
fun() {
local var="Sample value to be returned"
echo "$var"
#printf "%s\n" "$var"
}
Om du gör:
var="$(fun)"
utgången från fun
kommer att lagras i $var
.
Hantera flaggor och valfria parametrar
De inbyggda getopterna kan användas inuti funktioner för att skriva funktioner som rymmer flaggor och valfria parametrar. Detta innebär inga speciella svårigheter men man måste hantera de värden som berörs av getop på lämpligt sätt . Som ett exempel definierar vi en failwith- funktion som skriver ett meddelande på stderr och avslutas med kod 1 eller en godtycklig kod som levereras som parameter till alternativet -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}"
}
Denna funktion kan användas på följande sätt:
failwith '%s: File not found.' "${filename}"
failwith -x 70 'General internal error.'
och så vidare.
Observera att variabler inte bör användas som första argument för printf . Om meddelandet som ska skrivas ut består av innehållet i en variabel bör man använda %s
specifieraren för att skriva ut den, som i
failwith '%s' "${message}"
Utgångskoden för en funktion är utgångskoden för det sista kommandot
Överväg den här exempelfunktionen för att kontrollera om en värd är uppe:
is_alive() {
ping -c1 "$1" &> /dev/null
}
Denna funktion skickar en enda ping till värden specificerad av den första funktionsparametern. Utgången och felutgången från ping
omdirigeras båda till /dev/null
, så funktionen kommer aldrig att mata ut något. Men ping
kommandot har exitkod 0 på framgång och icke-noll vid misslyckande. Eftersom detta är den sista (och i detta exempel, är den enda) befälet över funktionen exit koden ping
kommer att återanvändas för utgången koden själva funktionen.
Detta faktum är mycket användbart i villkorade uttalanden.
Om till exempel graucho
är uppe ansluter du till den med ssh
:
if is_alive graucho; then
ssh graucho
fi
Ett annat exempel: Kontrollera upprepade gånger tills host graucho
är uppe och anslut sedan till det med ssh
:
while ! is_alive graucho; do
sleep 5
done
ssh graucho
Skriv ut funktionsdefinitionen
getfunc() {
declare -f "$@"
}
function func(){
echo "I am a sample function"
}
funcd="$(getfunc func)"
getfunc func # or echo "$funcd"
Produktion:
func ()
{
echo "I am a sample function"
}
En funktion som accepterar namngivna parametrar
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"
}
Exempel på användning:
foo -f
foo -t 10
foo -f --tail 10
foo --follow --tail 10