Kurzusok
/
Bash
Bash
/
Tanterv
/
Függvények
Fü

Függvények ebben a kurzusban: Bash

{one: "1 feladat", other: "%{count} feladat"}

A(z) Függvények fogalomról

Sok Bash-szkript szigorúan imperatív stílusban íródik: végrehajt egy parancsot, majd egy másikat, és így tovább. Néha együtt kell kezelned egy olyan parancssorozatot, amely fogalmilag egyetlen célt szolgál. Itt jönnek képbe a függvények.

Függvény definiálása

Egy függvényt így definiálsz:

my_function () {
    COMMANDS
}

Az üres zárójelpár egyszerűen azt jelöli, hogy egy függvényt definiálsz. Semmi sem kerül bele.

A függvény paraméterei

A függvények a definiálás után úgy viselkednek, mint bármely más parancs (akár beépített, akár nem). Ahogy bármelyik parancsnak, úgy a függvényeidnek is adhatsz argumentumokat. A függvényen belül a pozíciós paraméterekkel éred el az argumentumokat: $1, $2 és így tovább. (Emlékszel, a pozíciós paraméterekről a Változók fogalomnál tanultunk.)

Advanced

A speciális $0 paraméter egy függvényen belül nem változik meg; továbbra is a futó szkript neve. Az éppen futó függvény a $FUNCNAME változóból kérdezheti le a saját nevét.

Lásd a kézikönyv 3.4.2 Speciális paraméterek szakaszát.

Változók

Egy függvényen belül is definiálhatsz változókat. Ha a local paranccsal deklarálod őket, a változó scope-ja az aktuális függvényre korlátozódik (és minden olyan függvényre, amelyet az meghív). Ellenkező esetben a változó a globális scope-ba kerül.

A lokális változók neve megegyezhet egy globális változóéval. Ebben az esetben a lokális változó „árnyékolja” a globális változót. Ha például egy függvényben deklarálsz egy lokális változót, az elrejti az azonos nevű globális változót: a hivatkozások és az értékadások a lokális változóra vonatkoznak, a globális változó pedig változatlan marad. Amikor a függvény visszatér, a globális változó ismét láthatóvá válik.

x=5

myfunc () {
    local x=100
    echo "in my function, $x == 100"
}

echo "in the global scope, $x == 5"

myfunc

echo "back in the global scope, $x == 5"

Ennek a kimenete

in the global scope, 5 == 5
in my function, 100 == 100
back in the global scope, 5 == 5

Egy függvényen belül hozzáférhetsz a hívó scope-jában lévő változókhoz. Ez azt jelenti, hogy használhatod a globális változókat, valamint azokat a lokális változókat, amelyeket a hívó (vagy a hívót meghívó valamelyik függvény) deklarált.

Advanced

Szigorúan véve a „globális” nem a legtalálóbb szó. Ahhoz, hogy egy függvényben kifejtsen egy változót, a Bash felmegy a hívási veremen egészen a globális scope-ig, hogy megtalálja azt a függvényt, ahol ezt a változónevet deklarálták.

Ez a példa a kézikönyv Shell-függvények szakaszából származik, kisebb módosításokkal:

func1() {
    local var='func1 local'
    func2
}

func2() {
    echo "In func2, var = $var"
}

var=global
func1
func2

A kimenet:

In func2, var = func1 local
In func2, var = global

Hasonlóképp, ha értéket adsz egy változónak, az abban a scope-ban történik, ahol a változót deklarálták. Ez a „távolba ható művelet” nehezen követhető kódot eredményezhet, mert nem mindig nyilvánvaló, hol kapott értéket egy változó.

Advanced

A hívási verem a FUNCNAME tömbváltozóval vizsgálható meg.

Visszatérési értékek

Egy függvénynek, akárcsak bármely parancsnak, van kilépési státusza. Alapértelmezés szerint a függvény státusza az utolsó végrehajtott parancs kilépési státusza.

A return paranccsal adott kilépési státusszal térhetsz vissza egy függvényből.

check_password () {
    if [[ $1 == "secret" ]]; then
        return 0
    else
        return 1
    fi
}

read -sp "Enter your password: " pass

if check_password "$pass"; then
    echo "Correct!"
else
    echo "Wrong password."
fi

Ha a return-t argumentum nélkül használod, az az utolsó végrehajtott parancs státuszát adja vissza.

Note

Vegyük észre, hogy a check_password függvény leegyszerűsíthető így:

check_password () { [[ $1 == "secret" ]]; }
  1. A [[...]] feltételes szerkezetnek van kilépési státusza: 0 az „igaz”, 1 a „hamis” esetén.
  2. A {...} csoportosító szerkezetben a záró kapcsos zárójel előtt vagy egy sortörésnek, vagy egy pontosvesszőnek kell állnia.

A függvény kimenete

Egy függvény visszatérési státusza csupán egy szám. Hogyan tud akkor egy függvény kimenetet előállítani?

A függvényed a szabványos kimenetre írhat. A jól ismert parancsbehelyettesítéssel elkaphatod azt:

d6 () { echo "$(( 1 + RANDOM % 6 ))"; }

die=$( d6 )
echo "You rolled a $die."

A kimenet és a státusz együttes használata

A függvény kilépési státusza akkor is elérhető, amikor a kimenetét kapod el.

roll () {
    local n=$1
    if (( 4 <= n && n <= 20 )); then
        echo "$(( 1 + RANDOM % n ))"  # exit status is 0
    else
        return 1
    fi
}

read -p "How many faces does your die have? " faces
if die=$( roll "$faces" ); then
    echo "You rolled a $die."
else
    echo "I can't roll a die with $faces faces."
fi

Rekurzió

A függvények rekurzívan hívhatják önmagukat. Alapértelmezés szerint a rekurzió mélysége nincs korlátozva.

Egy példa:

fibonacci() {
    local n=$1
    if (( n <= 1 )); then
        echo "1"
    else
        local a=$(fibonacci "$(( n - 1 ))")
        local b=$(fibonacci "$(( n - 2 ))")
        echo "$(( a + b ))"
    fi
}

for i in {1..10}; do fibonacci "$i"; done
# => 1
# => 2
# => 3
# => 5
# => 8
# => 13
# => 21
# => 34
# => 55
# => 89
Advanced

A rekurzió mélysége a FUNCNEST változóval szabályozható.

bash -c '
    recur() {
        echo $1
        recur $(($1 + 1))
    }
    FUNCNEST=5
    recur 1
'
1
2
3
4
5
environment: line 1: recur: maximum function nesting level exceeded (5)
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg