• Nem Talált Eredményt

Függvények

In document Shell vagy héjprogramozás (Pldal 92-96)

Definíció

A függvények általában névvel ellátott kódszekvenciát jelentenek a programozási nyelvekben. A shell esetében is így van, mivel a nyelv interpretált, a függvény nevét és kódját felhasználás előtt, a program szövegében kell definiálni. Ez történhet a szkript elején vagy egy külön állományban, amelyet függvényhívás előtt beolvasunk.

A függvény kód szekvenciáját kapcsos zárójelek közt definiáljuk, a { }-ek közti részt a héj kód blokknak (code block) nevezi.

Ha külön állományban definiáljuk a függvényeket, akkor a . (dot) paranccsal kell őket az főprogramot tartalmazó állományba illeszteni.

A függvények úgy viselkednek mint egy-egy külön kis shell program. Argumentumaikat is ugyanúgy kapják (nem kell argumentumlistát definiálni) és a függvény testében az 1, 2, stb. változókkal érhetők el ($1, $2).

A függvény definíció szintaxisa:

function nev () {

#ide kerül a függvény kódja }

A nyitó kapcsos zárójel a név sorában is szerepelhet:

function nev () {

#ide kerül a függvény kódja }

Ugyanakkor a function kulcsszó akár el is hagyható, tehát a definíció ilyen is lehet:

nev () {

#ide kerül a függvény kódja }

Például:

function equal() {

if [ "$1" = "$2" ];then return 0

else

return 1 fi

}

Különböző héj szerkezetek

Fontos: a return parancs a függvény kilépési értékét küldi vissza, ez hívó héj ? változóját állítja be, ennek értéke lesz a return által visszaadott kód, és azt a $? hivatkozással érhetjük el a hívó szekvenciában, tehát nem eredmény visszatérítésre használjuk!

Így a függvény használata:

if equal "$a" "$b"

then

echo egyenloek fi

A függvények megosztják változóikat a hívó héjjal, vigyázni kell tehát a kilépési értékekre illetve a változómódosításra.

Ezek a megosztott változók un. globális változók. Ennek következtében a függvényben láthatóak a hívó szkript változói, és a a függvényben létrehozott változók láthatóak lesznek a hívó szkriptben.

Ha az equal függvényt egy equal.sh állományba írjuk, akkor a . paranccsal az alábbi módon használhatjuk az aktív héjban:

$. equal.sh

$equal "a" "b"

$echo $?

1

A . beolvassa a definíciót, és utána lehet használni ebből a héjból. Függvénydefiníciót törölni az unset parancsot használva lehet:

$unset equal

$equal "a" "b"

-bash: equal: command not found

$

Az unset két opciót fogad el, -v ha csak a megadott változóneveket, -f ha csak megadott függvényneveket akarunk törölni. Opció nélkül mindkettőt próbálja törölni.

A függvénydefiníciót megadhatjuk egyetlen parancssorban:

$ function hello () { echo "Helló" ; return 0; }

$ hello Helló

Ilyenkor az utolsó parancs után is meg kell jelennie a ; elválasztónak.

Bárhogyan adnánk meg a definíciót, annak meg kell jelennie a kódban a függvény használata előtt (a definíció bárhol lehet, nem kötelező a szkript elejére tenni)!

A függvények nem lehetnek üresek, tehát legalább egy parancsot kell tartalmazzanak.

Függvények érték visszatérítése

Az eredmények visszaadását a hívó szkriptnek az alábbi módszerekkel oldjuk meg:

1. globális változó beállítása

2. nyomtatás a függvényben és parancssor helyettesítés a hívásnál

Különböző héj szerkezetek

Az alábbi függvényt a getfname.sh állományban definiáljuk:

#visszaadja az állománynevet, levágva az extenziót

#egy bemeneti paramétere van

#ha több pont van a névben, az utolsótól a végéig vágja le

#a karaktereket

#ha nincs . , akkor a teljes nevet adja vissza function getfname()

{

#elhagyjuk az utolsó ponttól

#a név végéig terjedő szubsztringet echo "$1" | sed -r 's/(.+)(\.[^.]*)$/\1/' return

}

A sed parancs használatát lásd a parancsot bemutató fejezetben.

A függvény használata:

#!/bin/bash

. getfname.sh #függvény definíció betöltése fname="file.txt"

name=$(getfname $fname) echo $name

Az alábbi esetben viszont a függvényben létrehozott line változón keresztül tér vissza az érték (a függvénydefiníció a getline.sh fájlban található):

#egy sort olvas be és azt a line változóban adja vissza

#a főprogramnak vagy más függvénynek

#ha a felhasználó Ctrl-D-t üt be, akkor kilép

function getline {

line=""

if ! read -p "Kérek egy sztringet:" line then

echo "Olvasás hiba";

return 1 fi

return 0 }

Használata:

$. getline.sh

$ if getline ; then echo $line ; fi Kérek egy sztringet:piros

piros

$

Környezettel kapcsolatos kérdések

Különböző héj szerkezetek

A függvény megkapja a hívó héj munka könyvtárát, környezeti változóit. A függvényben létrehozott változók láthatóak lesznek a hívó héjban, és a függvény is látja az ott előzőleg létrehozott változókat.

Lokális változók használata

A Bash megengedi lokális változók használatát is. Ezeket a local kulcsszóval adjuk meg:

function teszt () {

local valtozo=3

local eredmeny=$(( valtozo * $1 )) echo $eredmeny

}

Ebben az esetben a valtozo és eredmeny változók nem lesz láthatóak a hívó héjban, még csak nem is írják felül az ott található ugyanolyan nevű változókat:

$ . teszt.sh

$ eredmeny=33

$ teszt 8 24

$ echo $eredmeny 33

$ echo $valtozo

$

Rekurzív hívások

Rekurzív hívás lehetséges. Azonban ha a rekurzív feldolgozás számításokat használ, amelyek paraméterként kell átadódjanak egyik szintről a másikra, meglehetősen nyakatekert kódot kapunk. Az alábbi függvény faktoriálist számol, és az eredményt egy fact nevű változóban téríti vissza:

#egy paraméterrel kell meghívni

#n! -t számol

function calc_fact1() {

if (( $1 == 0 )) ; then

fact=1 #ha n == 0 , akkor fact=1 return

else

calc_fact1 $(( $1 - 1 )) # (n-1)! marad a # fact-ban változoban

fact=$(( fact * $1 )) # fact n! lesz fi

return }

Ugyanez megoldható úgy is, ha az eredményt a ? változóban adjuk vissza, persze ezzel a $? -t nem rendeltetésének megfelelően használjuk. Az alábbi példában az n változót lokálisként használjuk (rekurzív hívások esetében ez a Bash tervezőinek ajánlata), így minden hívás esetében ismét létrejön:

function calc_fact() {

local n=$1 #n lokális if (( n == 0 )) ; then

Különböző héj szerkezetek

return 1 else

calc_fact $(( n - 1 )) # (n-1)!

return $(( $? * n )) # n!

fi }

Megjegyzendő, hogy a ? változóban a Bash esetében csak 255-nél kisebb egész számot lehet visszatéríteni (tehát annál nagyobb számokra a fenti függvény nem használható).

A rekurzió a héjban lassú, erőforrás igényes és ezért nem javasolt a használata.

In document Shell vagy héjprogramozás (Pldal 92-96)