Operációs rendszerek I. - UNIX felhasználói ismeretek és héjprogramozás
További vezérlő valamint számításokat megkönnyítő szerkezetek Tartalom 1. A case szerkezet...............................................................................................................................1 2. A select szerkezet.............................................................................................................................3 3. Aritmetikai kiértékelés: számítások a (( )) szerkezettel ..................................................................4 4. A C stílusú for ciklus........................................................................................................................6 5. Műveletek karakterláncokkal...........................................................................................................6 A shell programozását támogató megoldások száma elég nagy, az alábbiakban bemutatunk még néhányat, amelyek igen megkönnyítik a feladatok automatizálását.
1. A case szerkezet A case vezérlési struktúra hasonló a programozási nyelvek "switch" vezérléséhez: alternatív végrehajtási ágakra bontja a program parancsait. Az alternatívát egy karakterlánc mintákra való illesztése szerint hajtja végre. A következőképpen adjuk meg általános használati formáját: case valtozó minta1 ) minta2 ) . . . mintaN ) esac
in parancsok ;; parancsok ;; parancsok ;;
A szerkezetet case és esac kulcsszavak határolják. A szerkezet a megadott változóra illeszti a következő sorok elején található mintákat. Ahol a minta talál, ott végrehajtja a jobb zárójel utáni parancssorozatot amelyet két ; karakter zár le. Csak az első találatnak megfelelő alternatívát hajtja végre. A minta tulajdonképpen a shell minta: karaktereket illetve az állománynevek megadásánál használatos metakaraktereket lehet használni: * ? [] , valamint két minta "vagy" logikával való összekapcsolására a | -at. Példák: abc * ?bc ab|cd
pontosan abc-re illeszkedik bármire illeszkedik bármi az első karakter pozíción, és utána pontosan ab ab vagy cd láncokra illeszkedik
Példaként álljon itt egy állományokat könyvtárakba szortírozó program: #!/bin/bash #Leiras: #pelda a case alkalmazasara: szetvalogatja egy konytarbol a #pdf, mp3, avi, jpg, gif tipusu allomanyokat kulon konyvtarakba #egy argumentumot var: a konyvtarnevet ahol az allomanyok vannak #a celkonyvtarakat az alabbi valtozokban adom meg
1
Operációs rendszerek I. - UNIX felhasználói ismeretek és héjprogramozás PDF=pdf MP3=mp3 AVI=avi KEPEK=kepek #pontosan 1 parameter if [ -z "$1" ];then echo hasznalat: case.sh konyvtarnev exit 1 fi #megnezem, hogy a celkonyvtarak leteznek-e, #ha nem letrehozom oket #ha van pdf konyvtar, akkor az elso feltetel utan #abbahagyja a tesztet for konyvtar in "$PDF" "$MP3" "$AVI" "$KEPEK" do if ! [ -d "$konyvtar" ] && ! mkdir "$konyvtar" 2>/dev/null then echo nem lehet a $konyvtar konyvtarat letrehozni exit 1 fi done #vegigjarom a konyvtar allomanyneveit for f in $( ls "$1" ) do #itt hasznaljuk a case-t #a case-el valasztom es masolom kulonbozo helyekre #ha egy file egyik kategoriaba sem esik akkor a *-al #jelolt agra fut case "$f" in *.mp3 ) mv "$1/$f" "$MP3" ;; *.avi ) mv "$1/$f" "$AVI" ;; *.pdf ) mv "$1/$f" "$PDF" ;; *.jpg|*.gif ) mv "$1/$f" "$KEPEK" ;; * ) echo a $f nem tartozik egyik kategoriaba sem, marad. ;; esac done
Az alábbi kis program a parancssor kapcsolóit elemzi. Ha betartjuk azt a feltételt, hogy egy program hívásakor először a kapcsolókat, utána pedig az argumentumokat adjuk meg, akkor ez a szerkezet alkalmas kis programok kapcsolóinak kezelésére. #!/bin/bash while [ -n "$1" ] do case $1 in -f ) echo f kapcsolo ;; -c ) echo c kapcsolo ;; -* ) echo ismeretlen kapcsolo: $1;; #ha elérkeztünk az első argumentumhoz, amely nem kapcsoló: * ) break;; esac
2
Operációs rendszerek I. - UNIX felhasználói ismeretek és héjprogramozás shift
#eltoljuk a paramétereket, $1 a következő
done echo az elso kapcsolók utáni paraméter: $1
A program a -c és -f kapcsolót ismeri fel, ha futtatjuk: $bash switch.sh -c -f -g a b c kapcsolo f kapcsolo ismeretlen kapcsolo: -g az elso kapcsolók utáni paraméter: a $
Ha a kapcsolóknak is lenne paramétere, azok átvehetők a case ágaiban, de átvétel után még egy shift parancsot kellene végrehajtani. Megjegyzés: A shellnek van sokkal jobb megoldása az argumentumok kezelésére, a getopts függvény. De kis programoknál a fenti is megteszi.
2. A select szerkezet A select szerkezetet kis interaktív programok esetében használjuk. Használati módja: select valtozo in lista do parancsok done
A select kulcsszót tartalmazó sor végrehajtásakor a parancs egy kis menüt ír ki a lista (ez egy karakterlánc lista) segítségével. Ezek után készenléti jelet (prompter) ír ki (ezt a $PS3 shell változóból veszi). Válaszként a menü egyik sorát kell kiválasztani úgy, hogy a sorrendjének megfelelő számot ütjük le. Ezek után a select belsejében a valtozo értéke felveszi a listából kiválasztott karakterlánc értékét, és ezt fel lehet használni valamilyen parancsvégrehajtásra. Működését az alábbi kis példával illusztráljuk: #a PS3 értékét ajánlatos valamilyen ismerős prompt-ra #cserelni PS3='>>' select valtozo in Elso Masodik Harmadik Vege do echo $valtozo echo a '$REPLY' valtozo erteke ilyenkor: "$REPLY" #itt barmilyen parancsot vegre lehet hajtani, felhasznalva #a $valtozo es $REPLY ertekeit if [ "$valtozo" = 'Vege' ];then echo "...es jon a kilepes a select-bol" break
3
Operációs rendszerek I. - UNIX felhasználói ismeretek és héjprogramozás fi done
Működése pedig az alábbi: $ bash select.sh 1) Elso 2) Masodik 3) Harmadik 4) Vege >>1 Elso a $REPLY valtozo erteke ilyenkor: 1 >>2 Masodik a $REPLY valtozo erteke ilyenkor: 2 >> $
Addig ismétli a ciklust, amíg az állomány vége jelet (^D) ütjük le vagy kiválasztjuk a 'Vége' opciót.
3. Aritmetikai kiértékelés: számítások a ((
))
szerkezettel
Amint láttuk, az expr segítségéve elég kényelmetlen számolni. Az utóbbi évek fejlesztése során egyes shell értelmezők tartalmaznak néhány olyan kiterjesztést, amely könnyűvé teszi az egész számokkal való számítást (a POSIX szabvány is tartalmazza ezt, így a Korn shell is, valamint 2.04 verziótól kezdve a Bash is). Jelenlétére tehát nem lehet mindig számítani és elvileg hordozható programok esetén kerülni kell. Ezen kiterjesztések közül a két zárójellel határolt aritmetikai kiértékelést emeljük ki. Használata az alábbi: valtozo=$(( aritmetikai műveletek ))
pontosabban, használat közben: $ x=$(( 22 + 6 ))
A két határoló közti területen aritmetikai műveleteket lehet végezni, ugyanolyan szintaxissal mint a C nyelven történő programozásnál. A szerkezetet a teszteknél is lehet használni egész számokkal végzett tesztek esetében: i=4 while (( i > 2 )) do echo $i (( i-- )) done
Szabályok: -az operátorok a C nyelvből valóak, minden operátor használható 4
Operációs rendszerek I. - UNIX felhasználói ismeretek és héjprogramozás
-kiértékeléskor a Korn shell dupla pontosságú valós számokat használ (a Korn shell tud valós változókkal dolgozni). A Bash csak egész számokkal dolgozik. -a $ jelet nem kell változók előtt használni, de lehet. Kivételt képeznek a shell speciális változói, azok előtt viszont kell. Tehát: b=$(( a + 2 ))
, de: b=$(( $a + 2 ))
is helyes. A b=$(( $1 + 2 ))
összeadást viszont már csak a $ jel segítségével tudjuk elvégezni. -a dupla zárójelen belül nem érvényesek a shell behelyettesítések és metakarakterek, tehát * például használható szorzásra -a C hozzárendelő operátorai is használhatóak, pl. (( x+=2 ))
ebben az esetben viszont a $ jel nem használható a változó neve előtt: (( $x+=2 ))
#helytelen !!!
-zárójelezés használható -a relációs operátorok esetében az igaz értéke 1 – de csak a (( )) belsejében. A tesztek esetében a (( )) -ből való kilépés után a shell $? -t fordított értékre állítja. Tehát: $ (( 2 > 1 )) $ echo $? 0
így programban az alábbi módon használható: i=4 while (( i > 2 )) do echo $i (( i-- )) done
-nem kell feltétlenül ügyelni a szigorú, shell-nél megszokott szóköz elválasztóra operátorok és változók között, tehát írhatunk ((2+2)) -t vagy (( 2 + 2 )) -t is. -a hatványozás operátora a ** , ebben az esetben a két * karakternek egymás mellett kell állnia. Az alábbi szkript néhány példát tartalmaz: #!/bin/bash #peldak szamitasokra es kifejezes kiertekelesre a (( )) -tel #nehany segedvaltozo a=1 b=2 z=0 #hasznalhatok a C nyelv operatorai, a valtozonevek elott nem kell #a $ szimbolumot hasznalni
5
Operációs rendszerek I. - UNIX felhasználói ismeretek és héjprogramozás echo $(( a + 1)) #az sem szamit, ha nem tartjuk be feltetlenul a shell altal #kert szokozoket echo $((a+1)) echo $(( a++ )) #van egy eset, amikor kell $ szimbolumot hasznalni a nevek elott: #ha a shell specialis valtozoit hasznaljuk if [ -n "$1" ];then echo $(( $1 + 2 )) fi #a hatvany operator a ** echo $(( a**2 )) if (( 1 < b )) then echo '1 < b feltetel igaz' fi
4. A C stílusú for ciklus Az említett (( )) zárójeles szerkezet for ciklusok előállítására is használható, éspedig a C nyelv for utasításához hasonlóan. A szintaxis az alábbi: for (( i=0; i<10; i++ )) do shell parancsok #ezekben használható a $i változó . . . done Egy egészen egyszerű for ciklust tehát így írhatunk: #!/bin/bash for (( i=1; i<=10; i++ )) do echo $i done
Látható, hogy a tisztán egész számok végigjárására épülő ciklusokban ez kényelmesebben alkalmazható, mint az előző változatú, sztring lista végégjárására épülő for.
5. Műveletek karakterláncokkal A karakterláncok kezelésénél néha igen hasznos gyorsan elvégezni kis műveleteket, mint például: levágni egy karakterlánc elejét/végét vagy átírni egy részt a karakterláncban. Ezért amikor egy változót kiválasztunk a ${valtozo} szintaxissal, akkor a két {} zárójel közt operátorokat használhatunk erre. Az operátorok az alábbiak: ${valt#minta}
ha a minta illeszkedik a változóban levő karakterlánc elejére, akkor letörli a legkisebb illeszkedést és úgy téríti vissza a karakterláncot
${valt##minta}
ha a minta illeszkedik a változóban levő karakterlánc elejére, akkor letörli a legnagyobb illeszkedést és úgy téríti vissza a 6
Operációs rendszerek I. - UNIX felhasználói ismeretek és héjprogramozás
karakterláncot ${valt%minta}
ha a minta illeszkedik a változóban levő karakterlánc végére, akkor letörli a legkisebb illeszkedést és úgy téríti vissza a karakterláncot
${valt%%minta}
ha a minta illeszkedik a változóban levő karakterlánc végére, akkor letörli a legnagyobb illeszkedést és úgy téríti vissza a karakterláncot
${valt/minta/behelyetesít}
behelyettesíti a változóban a mintának megfelelő részt a ha minta #-el kezdődik a karakterlánc elején, ha % -al akkor a karakterlánc végén.
Példák: $ a=abcxyzabc $ echo ${a#abc} xyzabc $ echo ${a%abc} abcxyz $ echo ${a/xyz/abc} abcabcabc A duplázott %% és ## használata akkor indokolt, ha olyan mintát adunk meg, amelybe metakarakterek (*, ?) is vannak. Ezek egy karakterlánc esetében rövidebb vagy hosszabb illesztést
is meghatározhatnak. Például, az: abcxyzabcxyz
karakterlánc elejére a *abc minta (bármi és utána abc) rövidebben: abc (hiszen az üres karaktereklánc is bármi) vagy hosszabban: abcxyzabc is illeszkedhet. Így a # operátor a legrövidebb illesztést, a ## pedig a leghosszabbat fogja levágni. $ valtozo=abcxyzabcxyz $ echo ${valtozo#*abc} xyzabcxyz $ echo ${valtozo##*abc} xyz
Ezeket az operátorokat elég nehéz megjegyezni, a következőt szokták javasolni: A # jelet az angolok mindig valamilyen számosság jelölésére használják, és a szám elé teszik, pl. #10 , a % jelet pedig mindig a szám után tesszük, pl. 100% (innen a lánc elejére illetve végére utalás).
7