Loops – hurkok a shell scriptben

A legtöbb helyen a hurkokra (loops) egy jelzőt alkalmaznak: nagyon hasznosak. Ez teljesen igaz. Az egyik legjobban használható megoldás a schell scriptekben a hurkok. Az eddigi megoldásokban egy lineáris megoldásszerűséget alkalmaztunk, bár különféle feltelelek mellett, de sorban végezték el a feladatot. Ezzel most szakítani fogunk. Ideális lenne, ha valami olyant is megoldhatnánk, hogy egy feladatot addig végezzen el, amíg valami feltétel fennáll, vagy egy adott halmazra szépen egymásután, felhasználói beavatkozás nélkül tegye meg a megadott műveletet. Az egyik legegyszerűbb ilyen hurok már ismerős, a szekvencia generálásnál már volt róla szó. A mkdir {1..10} egy nagyon egyszerű megoldás, ha több egytől tízig nevű könyvtárat akarsz létrehozni. Ez a világ legegyszerűbb „hurka”: elkészíti az 1 könyvtárat, majd visszatér az elejére, megnézi, hogy van-e még feladat, majd készít egy 2 nevűt, majd…. eljut a 10-ig, elkészíti, majd nagyon jó érzéssel látja, hogy kész, és kilép a hurokból.

Mi a hurkok (loops) szerepe a shell scriptben?

A hurkok lehetővé teszik, hogy parancsok sorozatát elvégeztessük, és addig ismételjük őket, amíg egy adott helyzet meg nem változik, a feltétel, amit megadtunk már nem lesz igaz, vagy éppen eléri azt, hogy igaz lesz. Hasznosak az ismétlődő feladatok automatizálásában. A shell scripteknél most kettő alapvető szerkezetet ismerünk meg. Egy a közös bennük: figyelemmel kell összeállítani őket, mert a kezdeti időben nagy a hibázási lehetőség.

While Loops – „amíg” hurok a shell scripteknél

while [ tesztelendő feltétel ] 
do 
     feladatok sora
done

Ami azt jelenti, hogy addig végzi el az „elvégzendő feladat”-ban megadott parancsokat, amíg a tesztelendő feltétel igaz, ha már nem, akkor lép ki a ciklusból. Egy honlapon találtam ezt a jó kis ábrát::

Érdemes ránézni, és máris érthető a működése. Ha ilyen, vagy hasonló ábrákat rajzolunk fel egy-egy elképzelés, vagy működési vázlatként, akkor vizuálisan is látjuk a választási, működési sémát.

A megoldásnál egy jól átlátható példát szoktak emlegetni, írja ki az egész számokat egytől tízig. Ami azt jelenti, hogy: írd ki a kezdő egyest, majd adj hozzá egyet, amíg az a feltétel igaz, hogy a szám nem nagyobb, int tíz. Itt a példában fogadjuk el, hogy az tesztelendő feltételt így kell megadni. Majd a későbbiekben lesz szó a matekozásról a shell scriptekbe témáról is.

#!/bin/bash
# Alap while loop

counter=1
while [ $counter -le 10 ]
do
      echo $counter
      ((counter++))
done

echo „Kész vagyok!”

Nézzük meg egyesével a sorokat:

counter=1 A változó számlálóját a kiindulási értékkel inicializáljuk. Logikus feltételezés, hogy meg kell adni a kezdeti értéket egy sorozatnál. Ez az egyik hiba, ha abból indulunk ki, hogy a gép „úgyis tudja”, azt ami neked logikus. Ha az a feladat, hogy írd le tízig az egész számokat, akkor 1, 2, …10 és nem gondolkodunk el, hogy eggyel kezdjünk. A gép nem fogja tudni! Ha ilyen van, mindig adj meg egy kezdeti értéket.

while [ $counter -le 10 ] Amíg a teszt igaz (a számláló 10-nél kisebb vagy egyenlő), végezzük el a következő parancsokat.
A do után jönnek a parancsok, ami lehet egy, de lehet egy komoly, összetett rész is. Ha egy scriptben bizonytalan vagy, hogy az adott pillanatban mi az aktuális érték, akkor az echo a barátod! Kiíratod a terminálba és látod az aktuális eredményt.

echo $counter most ez az első feladat: írd ki a változó értékét!

((counter++)) A kettős zárójelben 1-rel növelhetjük a számláló értékét. Bár itt sima számlálás és kiíratás a cél, de magát a szerkezetet érdemes megjegyezni, mert így tudjuk a leggyorsabban emelni eggyel egy szám értékét.

Látja a program, hogy vége a parancs résznek, visszalép az elejére a while részig, hiszen ezzel azt mondjuk meg neki, hogy amíg az állítás igaz, addig dolgoznod kell. Újra megnézi, hogy a counter érték kisebb, vagy egyenlő a megadott értékkel. Ha igen, akkor megint elkezdi a feladatát (kiírja a counter értékét, ami már kettő, hiszen eggyel megemeltük a kezdeti értéket)
Majd megint ad hozzá egyet, látja, hogy vége a parancs résznek, előre megy, ellenőrzi… Majd eljut odáig, hogy nem lesz igaz a feltétel (itt 11 lesz a változó értéke), és kilép a hurokból.

done ismerős, ezzel zárjuk le a szakaszt, itt a vége tábla. Ezt akkor lépi át a programod, ha a ciklusban, a hurokban a feltétel mér nem igaz.

echo „Kész vagyok!” Egy jelzés számunkra, ami a kiírásnál egyértelműen jelzi, hogy bizony elvégeztük a feladatot és egy másik parancs jön. Itt is igaz, ha valamiben bizonytalan vagy, jelen esetben, hogy a hurok, a ciklikus feladatelvégzés hol ér véget, tegyél be egy echo-t amivel kiíratsz valamit.

Az előző példa addig írta ki a számokat AMÍG IGAZ volt az állítás. Logikus elvárás, hogy legyen egy olyan megoldás is, aminél azt adjuk meg, hogy addig dolgozz, amíg az állítás igaz nem lesz. Ez az

„addig, amíg” azaz az until loops megoldás

A szerkezete teljesen megegyezik az előbbivel, és igazi nagy különbség nincs is a kettő közt, alapesetben. Így a legtöbb shell scriptünkben akár az egyik, akár a másik megoldást használhatjuk.

A until loops szerkezete:

until [ feltétel ]
do
        parancsok sora
done

Az előbbi igencsak haszontalan, de példának jó script átirata:

counter=1

until [ $counter -gt 10 ]
do
     echo $counter
     ((counter++))
done

echo „Ez is kész”

Ami más az az until sor, ahol -gt 10 bejegyzéssel adjuk meg azt, hogy amíg egyenlő nem lesz tízzel, addig dolgozz!

Minek kettő? Mert sok esetben az egyik, vagy a másik értelmezése könnyebb. Az előző példa nagyon jó (nem én találtam ki, hanem olvastam), az a két scriptben a feladatod, hogy generáld le és írasd ki a számokat a kezdeti egytől a megadott tízig, azaz egy és tíz közt. Az ilyen egyszerűnek tűnő faladatban mindig kérdés lehet, hogy ha egy és tíz közt kell kiírni, akkor a kezdeti értéket értelemszerűen meg kell adni, de a tíz most benne van az elvárt sorozatban vagy nincs? A szokott vitatéma is jó: ha tizedikéig le kell adni a munkádat, akkor azt legkésőbb 9. nap éjfélig le kell adni, vagy jó lesz azt 10.-én is leadni?
Nekem a második megoldás egyértelműbb ebben az esetben, addig dolgozz, amíg a kapott szám tíz nem lesz! Bár kicsi a különbség, és mindegyikkel egyforma jó eredményt kapunk, de a kód gyors értelmezése miatt azt használd,a mi neked ott és akkor a legegyszerűbb.

A következő részt július 25.-re időzatettem!

Related Posts