=====Ciklusok=====
Ciklust akkor alkalmazunk, ha egy műveletet vagy műveletsort többször kell végrehajtani. Shell szkriptekben a **for**, a **while** és az **until** ciklusokat is alkalmazhatjuk.
====A for ciklus====
A for ciklust akkor alkalmazzuk, ha pontosan tudjuk, hányszor kell végrehajtani az adott műveletsorozatot. Az alábbi egyszerű szkript az **i** változónak ad 1, 3, 5, 7, 9 értékeket és végrehajtja a **do** és **done** kulcsszavak közötti parancsokat. Értelemszerűen annyiszor hajtja végre ahány elem van a felsorolásban:
#!/bin/bash
for i in 1 3 5 7 9
do
echo "$i a négyzeten = `expr $i '*' $i`"
done
A do és a done közötti sorokat ciklusmagnak is nevezzük.
palferi@lizi:~/proba$ ./c1.sc
1 a négyzeten = 1
3 a négyzeten = 9
5 a négyzeten = 25
7 a négyzeten = 49
9 a négyzeten = 81
A lista helyett bármilyen parancsot is írhatunk aminek a kimenete fog listát meghatározni. Gyakran alkalmazzák a seq (sequence, sorozat) parancsot:
for i in `seq 1 3 25`
do
echo "$i a négyzeten = `expr $i '*' $i`"
done
Itt a ''seq 1 3 25'' parancs egytől huszonötig listát hoz létre hármas lépéssel:
palferi@lizi:~/proba$ ./c1.sc
1 a négyzeten = 1
4 a négyzeten = 16
7 a négyzeten = 49
10 a négyzeten = 100
...
Az alábbi program a ''proba'' könyvtár fájljainak neveit és tartalmát listázza ki. Minden fájl 3 másodpercig látható és köztük 1 másodpercig sötét a terminál. Ezek után kiírja a ''proba'' könyvtár állományinak számát.
#!/bin/bash
N=0
for i in `ls ~/proba`
do
clear
sleep 1
echo "A fájl neve: $i"
cat ~/proba/"$i"
sleep 3
N=`expr $N '+' 1`
done
clear
echo "A ~/proba könytárban $N fájl van"
====A while ciklus====
A **while** ciklusnál az ismétlést egy feltételhez kötjük. Amennyiben a feltétel igaz, a ciklusmag végrehajtódik. A ciklusfeltétel a ciklusmag végrehajtása előtt értékelődik ki, ezért elképzelhető, hogy a ciklusmag egyszer sem hajtódik végre.\\
Az alábbi szkript kiszámítja a paraméterében megadott egész szám faktoriálját.
#!/bin/bash
I=1
F=1
while test $1 -ge $I
do
F=`expr $F '*' $I`
I=`expr $I '+' 1`
done
echo "$1! = $F"
Vizsgáljuk meg a program működését. Az alábbi táblázat a változók értékeit mutatja a ciklusmag három ismétlődésekor és a ciklus végét, ha a paraméter 3:
^ 1. ellenőrzés ^ 2. ellenőrzés ^ 3. ellenőrzés ^ 4. ellenőrzés ^
|a feltétel igaz: 3>=1|a feltétel igaz: 3>=2|a feltétel igaz: 3>=3|a feltétel HAMIS: 3>=4|
| F=1*1=1 | F=1*2=2 | F=2*3=6 | |
| I=1+1=2 | I=2+1=3 | I=3+1=4 | |
| | | | F=6 |
Az alábbi, ''c4.sc'' néven létrehozott szkript a paraméterbe megadott egész szám osztóit írja ki. Meghatározza az osztók számát, és ha ez a szám kettő, a prímszám szöveg jelenik meg.
#!/bin/bash
I=1 ; F=1 ; OT=1
while test $1 -gt $I
do
F=`expr $1 '%' $I`
if test $F -eq 0
then
echo " $I"
OT=`expr $OT '+' 1`
fi
I=`expr $I '+' 1`
done
echo " $1"
if test $OT -eq 2
then
echo "$1 - prímszám!"
else
echo "$1 -- $OT osztója van"
fi
Indítsuk a szkriptet különböző paraméterekkel és ellenőrizzük működését:
palferi@lizi:~/proba$ ./c4.sc 719
1
719
719 - prímszám!
palferi@lizi:~/proba$ ./c4.sc 81
1
3
9
27
81
81 -- 5 osztója van
====A until ciklus====
A **until** ciklus felépítésben hasonlít a while-hoz, azonban ebben az esetben a **do** és **done** közötti utasítások addig hajtódnak végre, míg a feltétel igazzá nem válik.
=====Tömbök használata=====
Shell szkriptekben használhatunk egydimenziós tömböket. A tömbök elemeinek indexe egész szám, a sorszámozás nullától indul. A **B** tömb hármas indexű eleme: ''B[3]''\\
A tömb hármas indexű elemének értéke pedig: ''${B[3]}''
A tömb összes elemére hivatkozhatunk a ''*'' karakterrel: ''${B[*]}''\\
A következő feladat a tömbök használatát és az **until** ciklust mutatja be.
====Feladat 1. Minimumkeresés====
Írjunk szkriptet ''c5.sc'' néven ami beolvas tömbbe **n** egész számot. Az **n** értékét az első paraméterben adjuk meg. Az **until** ciklus használatával határozzuk meg a tömb legkisebb elemét.
#!/bin/bash
for i in `seq 1 $1`
do
echo -n "$i. szam: ?"
read TOMB[$i]
done
echo "A tömb $1 elemből áll: ${TOMB[*]}"
MIN=${TOMB[1]}
H=2
until test $H -gt $1
do
if test ${TOMB[H]} -lt $MIN
then
MIN=${TOMB[H]}
fi
H=`expr $H '+' 1`
done
echo "A tömb legkisebb eleme: $MIN"
A programban a **for** ciklus változója az **i**, egytől az első paraméterben megadott számig veszi fel az értékeket. A ciklus magja megjeleníti a sorszámot és a **read** paranccsal beolvassa a tömb megfelelő elemeit. Ezután kiírja a tömb elemeinek számát és a minden elemét.\\
A ''MIN'' változó fogja a tömb legkisebb elemét tartalmazni, de először az első elem értékét kapja. A ''H'' változó kezdeti értéke 2, hiszen a tömb második elemétől kell mindegyiket összehasonlítani a ''MIN'' változó értékével.\\
Ezt az **until** ciklus végzi. A ciklus magjában az adott elemet összehasonlítjuk a ''MIN'' értékével, és ha kisebb annál, akkor az adott elem lesz a ''MIN''. A ''H'' értékét is növeljük eggyel a ciklusmagban, amikor olyan értéket kap, hogy a ''H'' nagyobb lesz mint a paraméterben megadott szám, a ciklus véget ér. A ciklus végeztével a ''MIN'' változó tartalmazza a tömb legkisebb elemét:
palferi@lizi:~/proba$ ./c5.sc 4
1. szam: ?54
2. szam: ?3
3. szam: ?9
4. szam: ?7
A tömb 4 elemből áll: 54 3 9 7
A tömb legkisebb eleme: 3
====Feladat 2. Rendezés====
Módosítsuk az előző szkriptet hogy a tömb elemeit rendezze buborék algoritmussal. Az algoritmusról részletesen itt olvashatunk: [[http://hu.wikipedia.org/wiki/Bubor%C3%A9krendez%C3%A9s| Wikipédia - Buborékrendezés]]\\
Az algoritmus pseudokódja a következő:
FOR J=1 TO N-1 STEP 1
FOR I=1 TO N-J STEP 1
IF A[I]>A[I+1] THEN SWAP A[I],A[I+1]
NEXT I
NEXT J
A csere (SWAP) parancsot megvalósíthatjuk az alábbi sorokkal:
TEMP=A[I]
A[I]=A[I+1]
A[I+1]=TEMP
Ezek alapján a szkript:
#!/bin/bash
for i in `seq 1 $1`
do
echo -n "$i. szam: "
read TOMB[$i]
done
echo "A tömb $1 elemből áll: ${TOMB[*]}"
# rendez
JJ=`expr $1 '-' 1`
for J in `seq 1 $JJ`
do
KK=`expr $1 '-' $J`
for K in `seq 1 $KK`
do
KN=`expr $K '+' 1`
if test "${TOMB[K]}" -gt "${TOMB[KN]}"
then
TEMP=${TOMB[K]}
TOMB[K]=${TOMB[KN]}
TOMB[KN]=$TEMP
fi
done
done
echo "A rendezett tömb: ${TOMB[*]}"
Próbáljuk ki a működését:
palferi@lizi:~/proba$ ./c6.sc 7
1. szam: 23
2. szam: 7
3. szam: 3
4. szam: 9
5. szam: -9
6. szam: 0
7. szam: 2
A tömb 7 elemből áll: 23 7 3 9 -9 0 2
A rendezett tömb: -9 0 2 3 7 9 23
[[st-linux_alapok:st-linux_alapok|< Vissza]]