Operációs rendszerek I. - UNIX felhasználói ismeretek és héjprogramozás, 2009-10-es tanév
7. Laboratóriumi gyakorlat, 1. rész : Vezérlési szerkezetek II. A gyakorlat célja: 1. A shell vezérlő szerkezetei használatának gyakorlása. A használt vezérlő szerkezetek: if/else/fi, for, while while, select, case, shift.
2. A ${} sztring operátorainak használata 3. A (( )) számításokat elősegítő szerkezet használata
Előkészülethez szükséges anyag: a 6. és 7. előadás segédlete és a felhasznált parancsok kézikönyv lapjai illetve rövid leírásai. A gyakorlat menete: 1. Az if szerkezet .................................................................................................................................1 2. A for ciklus ......................................................................................................................................2 3. A read parancs .................................................................................................................................2 4. A while és until szerkezetek ............................................................................................................3 5. A case szerkezet és a shift................................................................................................................4 6. Sztring operátorok a ${} szerkezetben.............................................................................................4 7. Számítások a (( )) szerkezettel..........................................................................................................5 Megoldott feladatok .............................................................................................................................5
1. Az if szerkezet Írjunk szkriptet amelyik ... 1. ... if szerkezettel eldönti, van-e legalább egy argumentum a parancssoron. Ha van, akkor kiírja az argumentumok számát. 2. ... kiírja, hogy két argumentuma közül az első vagy a második a nagyobb mint szám. Ha nem adunk meg pontosan 2 argumentumot hibaüzenettel kilép. 3. ... az argumentumában megadott állományról kiírja, hogy olvasható, írható ás végrehajthatóe a felhasználó által. Ha a jogok nincsenek beállítva, azt írja ki, hogy nem olvasható, stb. 4. ... ha a parancssoron megadott állomány könyvtár, kiírja, hogy könyvtár, belép a könyvtárba, és kilistázza a benne levő állományok nevét. ha nem könyvtár, akkor csak az állományra ad listázást. Mindkét esetben mielőtt listázna, kiírja, hogy mit fog csinálni. 5. ... ha a parancssoron megadott állomány olvasható és írható, akkor kilistázza az állomány utolsó 10 sorát, és utána az állomány végére írja, hogy "Listázva". Ha nem teljesül mindkét feltétel, akkor kiírja: "Rossz jogok az ... állományon." (pontok helyett az állomány neve). 6. ... ha a parancssor első és negyedik argumentuma mint sztring egyenlő, kiírja: "rossz argumentumok". 7. ... ha a parancssor 4. argumentuma zéró hosszú sztring, kiírja: "4. argumentum zéró hosszúságú" 1
Operációs rendszerek I. - UNIX felhasználói ismeretek és héjprogramozás, 2009-10-es tanév
Írjunk egy szkriptet amelyik kiírja, hogy első argumentuma kisebb vagy nagyobb mint a parancssoron levő több argumentum! (tehát legalább 2 argumentumot kell neki megadni, de lehet akár tízet is).
2. A for ciklus Az alábbi kis szkripteknek SOHA SEM SZABAD ROSSZ ARGUMENTUMOK MIATT HIBÁZNIUK, ezért: minden hibalehetőséget tesztelni kell, és ha szükséges le kell állítani a szkriptet a hiba kiírásával és zérótól különböző kilépési kóddal. Írjunk egy szkriptet, amelyik ... 1. ... végigjárja a munkakönyvtárunk állományait, és kiírja nevüket. Módosítsuk ezt a szkriptet az alábbiakkal: -Ne a munkakönyvtárt, hanem az első parancssori argumentumban megadott könyvtárat járjuk végig. -Ne csak a nevüket írjuk ki, hanem azt is ha olvashatóak. -Ha a végigjárt állomány könyvtár írjuk a neve után zárójelbe, ugyanabba a sorba (könyvtár). 2. ... amelyik létrehozza az argumentumaiban megadott nevű könyvtárakat a munkakönyvtárunk alá. Ha nem adunk meg argumentumokat, vagy valamelyiket nem lehet létrehozni, hibát ír ki. Írja ki minden alkalommal amikor sikerült egyet létrehozni. 3. ... kiírja a számokat 1-től 10-ig és utánaírja az összegüket. Módosítsuk, hogy a parancssoron megadott 2 argumentum közti számokat és azok összegét írja ki. A seq parancsot fogjuk használni a számok generálására. 4. ... a /etc/passwd állományban levő felhasználóneveket járja végig. Csak azokat írja ki ahol a felhasználó login vevének hossza pontosan 4. A shell alatt egy változó hosszát több módon kiszámolhatjuk, pl. a user változó hosszát kiírhatjuk az alábbi echo parancsokkal (a sorok elején levő $ jel a shell készenléti jele): $ user="eva" $ echo ${#eva} 3 $ echo -n $user | wc -c 3
5. ... végigjárja a parancssoron megadott könyvtár állományait. Ha közönséges állományt talál kiírja a nevét. ha könyvtárat, akkor belép és végigjárja az ott levő állományokat, ugyancsak a nevüket írja ki. Utána visszalép az első szintre. Hogyan írnánk meg egy olyan szkriptet, amelyik "akárhány" szintig elvégzi az előbieket? 6.
... végigjárja egy kis szöveges állomány sorait. Pl. töltsük le a words1 állományt és járjuk végig és írjuk ki a benne levő szavakat egy for ciklussal. Írjuk ki csak az 5 karakter hosszú szavakat.
3. A read parancs Olvassuk át a read parancs kapcsolóit a segédletből és végezzük el a következőket: 2
Operációs rendszerek I. - UNIX felhasználói ismeretek és héjprogramozás, 2009-10-es tanév
1. Olvassuk be egy változóba az alábbi sorokat (külön-külön): a abc def abc def ghi
2. Olvassuk be két változóba ugyanazokat a sorokat. Mit tapasztalunk? 3. Írjunk ki készenléti jelet (pl. "Írj be egy sort:") a read -el! 4. Olvassunk be csak egy karaktert a read-el egy változóba! 5. Írjunk programot, amely végigolvas a read-el egy szöveges állományt úgy, hogy az állomány sorai külön-külön feldolgozhatóak egy while ciklus belsejében! 6. Ellenőrizzük, mennyi a read visszatérítési értéke ha állomány vége jelet ütünk be olvasáskor ( ^D )?
4. A while és until szerkezetek Írjunk kis ciklusokat amelyek az alábbiakat valósítják meg: 1. Olvassunk be sorokat a terminálról és írjuk vissza a sorok hosszát addig amíg EOF karakter ütünk be. Módosítsuk a programot úgy, hogy addig olvasson sorokat amíg egy kis a betűt ütünk be. Adjunk erre a feladatra 2 megoldást. 2. Írjunk egy ciklust amelyik addig várakozik 2 másodperces sleep parancsokat végrehajtva, amíg az 1.txt nevű állomány létrejön. utána kilép a ciklusból és kiírja: "1.txt megjelent!". Írjuk meg a programot: -while ciklussal -until ciklussal A teszteléshez egyik terminálon futtatjuk a szkriptet, a másikon pedig a touch -al létrehozzuk az 1.txt állományt. 3. Járjuk végig egy állomány sorait úgy, hogy egy olyan szkriptnek, amelyik while read line do #feldolgozás done
típusú feldolgozást tartalmaz a standard bemenetére egy szöveges állományt irányítunk. Végigjárás közben írjuk ki a.) a sorok számát a sorok elé és a sorokat b.) a sorok számát és a sorban levő szavak számát a sorok elé 4. Egy állomány sorait végigjárva találjuk meg a leghosszabb sort és írjuk ki azt a while ciklus befejeztével.
3
Operációs rendszerek I. - UNIX felhasználói ismeretek és héjprogramozás, 2009-10-es tanév
5. A case szerkezet és a shift 1. Írjunk egy olyan szkriptet amely a case szerkezet segítségével írja ki nekünk, hogy milyen billentyűt ütöttünk be: kisbetűt, nagybetűt, számjegyet vagy egyéb karaktert. A program olvasson egy ciklusban egyenként karaktereket a read-el, addig amíg EOF jelet nem kap. 2. A lista.txt (letöltés) állományban termékkódok és darabszámok vannak valamilyen raktári nyilvántartásból. Készítsünk egy héjprogramot, amely kódok szerint szétválogatja 3 állományba a sorokat: az elsőbe azok kerülnek, amelyeknél a kód P-vel kezdődik és kisbetűvel folytatódik valamint azok amelyek a kód Q-val kezdődik, a másodikba azok amelyek P-vel kezdődnek, második betűjük pedig szám, valamint azok amelyek R-el kezdődnek, a harmadikba azok amelyek P-vel kezdődnek és a második betűjük nagy betű. A három állomány neve 1.txt, 2.txt és 3.txt. Mindhárom végére oda kell még "ragasztani" egy sort, amelyben az szerepel, hogy az illető állományban hány sor van van. A program írja ki azt is, ha talál olyan sort, amelyet nem tud osztályozni. 3. Teszteljük le a parancssor paramétereit a case struktúrával: milyen kapcsolók vannak rajta? Legyenek pl. -a, -b, -c kapcsolók egy program számára, és a -b kapcsolónak legyen egy kötelező paramétere. Például az alábbi programindításnál: prog.sh -a -b x -c arg1
a program írja ki: a kapcsoló b kapcsoló és argumentuma x c kapcsoló az arg1 az elso kapcsoló nélküli argumentum
A kapcsolókat mindig az argumentumok előtt adjuk meg. Használjuk fel a shift parancsot is a tesztelés írásakor. 4. Írjuk ki egy while szerkezettel a parancssor minden második paraméterét a shift -et használva.
6. Sztring operátorok a ${} szerkezetben 1. Írjuk be egy állomány teljes elérési útját egy változóba, pl: file='/home/eva/teszt.txt'
Írjuk ki echo paranccsal: -csak az állomány nevét 4
Operációs rendszerek I. - UNIX felhasználói ismeretek és héjprogramozás, 2009-10-es tanév
-a könyvtár nevét amelyben található, teljes elérési úttal -az elérési utat alkotó könyvtárak nevét külön-külön -az állománynév kiterjesztését. 2. Írjunk olyan programot amely átnevez minden .sh típusú állományt .bash típusúvá egy könyvtárban. Az állomány típus karakterláncának leválasztásakor használjuk fel a ${} belsejében alkalmazható karakterlánc operátorokat. A program legyen nagyon biztonságos: nehogy véletlenül is elvesztődjenek az állományok az átnevezés alatt.
7. Számítások a (( )) szerkezettel 1. Írjunk egy olyan szkriptet amelyik a terminálról olvas 2 számot (n1, n2), és utána n1 ciklust végez, mindegyik ciklusban beolvas egy harmadik számot (n3). Ha n3 egyenlő n2-vel hagyjuk abba a ciklust. 2. Számoljuk ki egy szkripttel, hogy egy könyvtárban levő állományokban összesen hány byte és kilobyte van. 1 kilobyte-ot 1024 byte-nak számolunk.
Megoldott feladatok A programok a pelda7.tgz állományban vannak. Kipakolás: $ tar -xzv -f pelda7.tgz
1. Olvassunk végig egy szöveges állományt. Miközben kiírjuk a sorokat a terminálra , írjuk a sorok elé a sor számát, utána pedig a sorban levő karakterek számát ( sorok.sh ). 2. Írjunk egy programot amely végrehajthatóvá teszi az argumentumaiban megadott állományokat – egyenként. Minden művelet előtt nézze meg, hogy az illető állomány létezik-e., utána kérdezze meg minden egyes létező állománynál, hogy végezze-e el a műveletet vagy nem: i vagy n karakterekkel válaszoljunk a kérdésre ( toexec.sh ). 3. Adjuk össze a számokat 1-től n-ig az expr és seq parancsot használva! (summa.sh) 4. Szűrjük ki a '\r' (kocsi vissza) karaktereket egy adott könyvtárban levő adott típusú forrásállományokból (.c , .java. stb. típusú állományok). A szűrés után az állományok maradjanak ugyanolyan név alatt ugyanabban a könyvtárban (dosunix.sh). Megjegyzés: a Linux alatt létezik egy dos2unix program, mint parancs, amelyik megoldja ezt a feladatot parancsszinten, lásd man dos2unix . 5. Írjunk egy programot, amely kilistázza egy shell szkript első sorait, mindaddig míg a sorok első karaktere a # (help.sh) . 6. Írjunk egy programot amelyik egy könyvtárból kilistázza az ott található szöveges (.txt típusú) állományok első és utolsó sorát, valamint a sorainak számát. Az 1.txt nevű állomány esetében, amelynek első sora abc, utolsó pedig xyz és 22 sort tartalmaz, a kimenet így nézzen ki: File: 1.txt : 22 sor E: abc U: xyz
5
Operációs rendszerek I. - UNIX felhasználói ismeretek és héjprogramozás, 2009-10-es tanév
(a példaprogram firstlast.sh). 7. Írjunk egy programot, amelyik megszámolja, hogy a $PATH változóban levő könyvtárakban összesen hány bináris futtatható állomány van. A $PATH tartalma például nálam így néz ki: /usr/lib/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/.
A következőket csináljuk: -átírjuk a kettőspontokat szóközzé, majd a listát egy változóhoz rendeljük -végigjárjuk a listát és kilistázzuk az egyes könyvtárak tartalmát ls -1 paranccsal -a wc és expr programokkal megszámoljuk, hogy hány állomány van a listákban A program neve binfiles.sh .
6