Előadást letölteni
Az előadás letöltése folymat van. Kérjük, várjon
KiadtaAlexandra Dobosné Megváltozta több, mint 6 éve
1
Számítógépes alapismeretek Shell script programozás
Kizárólag emlékeztető, a gyakorlaton történő részvételt nem pótolja.
2
Bevezető ismeretek egy sorba több parancs is írható, a ; az elválasztó
who -q;date # jel után megjegyzést tudunk írni A scriptet tetszőleges szövegszerkesztőben elkészíthetjük A script első sora tartalmazza, a parancsértelmező elérhetőségét (#! jel után) #!/bin/bash A whereis bash parancs megmutatja az útvonalat
3
Dátum kiírása script Szövegszerkesztőben készítsük el a datum.sh scriptet Hogyan futtathatjuk? parancsnév [amennyiben a PATH változóban szerepel az útvonal] ./parancsnév bash parancsnév #!/bin/bash echo Az aktuális dátum és idő: date
4
Dátum kiírása script Ha csak így futtatjuk: datum.sh
bash datum.sh (ilyenkor nem kell végrehajtási jog, elég az olvasási) ./datum.sh Adjunk x jogot! chmod u+x datum.sh Futtassuk újra! -bash: datum.sh: command not found Az aktuális dátum és idő: 2009. szept. 29., kedd, CEST Hozzáférés megtagadva Mert nincs végrehajtási (x) jog a fájlon. Az aktuális dátum és idő: 2009. szept. 29., kedd, CEST
5
Bejelentkezés utáni script futtatás
A .profile állomány tartalma bejelentkezéskor lefut Legyen a tartalma: Jelentkezzünk be a gépre újból! Itt miért nem kell a #!/bin/bash sor? Mert az aktuális (bash) shellben hajtódik végre echo Üdvözöllek! Az aktuális dátum és idő: date
6
Aliasok használata Ha egy gyakran használt parancsot rövidebb formában akarjuk elérni: Alias elnevezés= ”parancs” Példa: alias lla="ls -al" Ha már nem akarjuk használni Unalias elnevezés unalias lla Alias-ok lekérdezése: alias Készíts egy aliast web néven, ami – akármelyik könyvtárba is állsz eredetileg - a public_html könyvtáradba lép be.
7
Környezeti változók env paranccsal lekérdezhető
A PS1 az elsődleges prompt A változó értékére $ jellel hivatkozhatunk. Pl. echo $PS1 Jelentés: \u= usernév, \h=hostnév, \w: munkakönyvtár; \$: ha nem vagyunk root jogúak, akkor $-t, egyébként #-t jelenít meg KRB5CCNAME=FILE:/tmp/krb5cc_33944_SOhBf13780 SHLVL=1 HOME=/h/oktatok/MediaEsOktatasinformatika/gipszjakab LANGUAGE=hu_HU.UTF-8 Egy folyamat környezete mindazt az információt jelenti, amit a folyamat az őt futtató operációs rendszerről, gépről, beállításokról megtudhat. Ezeket az információkat többnyire változókban tároljuk (név-érték párok). Ezek a változók létrejönnek a shell indításakor, és úgy fér hozzájuk mint saját változóihoz. Többnyire nagy betűs változó nevekkel ábrázoljuk ezeket, különbséget téve így (a programozó számára) a saját, illetve az operációs rendszertől kapott változók közt.
8
Változtassuk meg az elsődleges promptot!
export PS1="\w$>" Eredmény: ~/public/public_html$> Ha minden bejelentkezés után ezt szeretnénk, akkor a parancsot .profile állományban kell elhelyezni Lehet színezni a promptot. ( ) export PS1="\e[32;40m\w>" export PS1="\e[31;46m\w>" export Állítsd be, hogy így nézzen ki a prompt!
9
Másodlagos prompt PS2: másodlagos prompt
Amennyiben több bemenetre van szükség, ez a prompt látszik echo $PS2 > Példa (zárójellel csoportosíthatom a parancsokat) ( >ls –al >) Változtasd meg a másodlagos promptot a következőre: #folytasd>
10
Path változó tartalma Path: Elérési útvonalak Példa
echo $PATH /usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games Módosítsuk úgy, hogy az aktuális könyvtár is benne legyen export PATH=$PATH:.
11
Változók kiírása set parancs megmutatja az összes változót
Saját változó készítése A név betű, szám és aláhúzás lehet n=15 echo $n 15 nevem= ”Gipsz Jakab Jenő” echo $nevem Gipsz Jakab Jenő Fontos! Scriptben nem látjuk az eredményt! Idézőjel kell, mert szóközt tartalmaz!
12
Script példa #!/bin/bash echo $n echo $nevem
Környezeti változóvá kell alakítani (export), hogy a scriptben is lássuk! A változót az unset paranccsal törölhetjük. Példa: unset n
13
Játék a változókkal A \ jel megszünteti a következő karakter hatását
‘ ‘ jelek között szintén megszűnik a hatás Idézőjelek között megmarad
14
A {} jelölés Új változót használok, vagy a régi nevére hivatkozok? Nem egyértelmű, ezért a {} jelek között jelezni kell a változó nevét jelentő karakterláncot ha a változó nem létezik, nem ad értéket a változónak, de visszatéríti a Marok szót ha a változó nem létezik, értéket ad a változónak, és visszatéríti a Marok szót
15
Változók a=mobil; b=telefon Mit fognak kiírni az alábbi parancsok?
echo ab ab echo $ab semmit echo $a$b mobiltelefon echo ${ab} echo ${a}${b} echo ${c:-3} ${c} 3 echo ${c:=2} 2
16
Változók Mit fognak kiírni az alábbi parancsok? echo "\"" echo '\"'
echo "$a$b" mobiltelefon echo '$a' $a
17
Parancs behelyettesítése
`parancs` (Alt Gr + 7) vagy $(parancs) formátumban behelyettesíthetjük a parancsot Vigyázzunk melyik aposztrófot használjuk! A karakterláncban megadott parancs is végrehajtható
18
Paraméterek használata
$0: parancs neve $1,$2,…: paraméter változók $9: 9. paraméter ${10}: 10.paraméter ($10 nem jó) $#: paraméterek száma $*: összes paraméter stringként összes paraméter stringek sorozataként
19
Param.sh $ bash param.sh alma körte barack Parancs neve:param.sh
Első paraméter:alma Második paraméter:körte Paraméterek száma:3 Összes paraméter - stringként:alma körte barack Összes paraméter - string sorozataként:alma körte barack $* esetén:1 paraméter lett megadva. esetén:3 paraméter lett megadva. #!/bin/bash echo -n Parancs neve: echo $0 echo -n Első paraméter: echo $1 echo -n Második paraméter: echo $2 echo -n Paraméterek száma: echo $# echo -n Összes paraméter - stringként: echo $* echo -n Összes paraméter - string sorozataként: echo function hany_param { echo "$# paraméter lett megadva." } echo -n \$* esetén: hany_param "$*" echo -n esetén: hany_param
20
Read parancs A read parancs beolvas egy sort a parancssorról egy változóba vagy változó listába. Ha egy változót adunk meg a parancssorán, akkor a teljes sort abba olvassa, ha többet akkor a sort feldarabolja a shell implicit elválasztói szerint (szóköz és tabulátor) és a változók felveszik a szavak értékeit. read sor read szo1 szo2 szo3 az egész sort a $sor-ba téríti vissza a beütött szavakat a szo1, szo2 stb. -be írja
21
Read parancs Fontosabb opciók -p prompt -s silent -t timeout -n nchar
kiír egy készenléti jel karakterláncot olvasás előtt -s silent nem használ visszhangot, tehát nem látjuk a leütött betűket: jelszó beolvasásra jó -t timeout vár timeout másodpercig, ha az alatt nem ütünk be semmit, visszatér -n nchar csak nchar darab karaktert olvas, utána visszatér -d kar delimiter más elválasztót keres a sorok végén mint az újsor karaktert
22
Read parancs (példa) $ read -p "Írd be a neved:" nev Írd be a neved:Gipsz Jakab $ echo $nev Gipsz Jakab Az alábbi megoldás 3 másodpercig vár, és csak egy karaktert olvas be az $igen_nem változóba, utána visszatér. $ read -p "Igen vagy nem [I/N]?:" -n 1 -t 3 igen_nem Igen vagy nem [I/N]?:i$ $ echo $igen_nem i
23
Gyakorló feladat Írj egy scriptet (parancs.sh), amely read paranccsal bekér egy parancsot (pl. who), majd megmutatja az erre a vonatkozó használati útmutatót (man) majd végrehajtja a parancsot! #!/bin/bash echo -n Kérem a parancsot! read parancs man $parancs $parancs
24
Kimenet, bemenet, átirányítás I.
Kimenet, bemeneti eszközök stdin (0) -billentyűzet, alapértelmezett bemenet stdout (1) -monitor, alapértelmezett kimenet stderr (2) –monitor, alapértelmezett hibakimenet Átirányítás –Kimenet: > jel segítségével echo alma barack szilva >gyumolcs –Bemenet: < jel segítségével Pl: mail < level.txt
25
Kimenet, bemenet, átirányítás II.
Kimenet, hozzáfűzés (append) >> fájlnév, Pl: echo dió >>gyumolcs Ha nem létezik a fájl, akkor létre is hozza! Hibakimenet (stderr) átirányítás 2>, 2>> Kimenet és hiba átirányítása (parancs >fájl 2>hibafájl) $ ls ilyen_nincs ls: ilyen_nincs nem érhető el: Nincs ilyen fájl vagy könyvtár ls ilyen_nincs 2>/dev/null $ $ cat nincs_ilyen.txt >sz.txt 2>hiba.txt $ cat sz.txt $ cat hiba.txt cat: nincs_ilyen.txt: Nincs ilyen fájl vagy könyvtár $ cat van_ilyen.txt >sz.txt 2>hiba.txt van
26
Kimenet, bemenet, átirányítás II.
Program kimenet és hiba ugyanabban az állományban Bemenet átirányítás a helyben megadott szövegre (<<) $ ls nincs_ilyen.txt > hiba.txt 2>&1 $ cat hiba.txt ls: nincs_ilyen.txt nem érhető el: Nincs ilyen fájl vagy könyvtár $ ls van_ilyen.txt > hiba.txt 2>&1 van_ilyen.txt $ cat <<alma > körte > barack > alma körte barack $
27
Gyakorló feladat Írj egy olyan scriptet (atiranyit.sh), amely az első paraméterben megadott parancsot végrehajtja és a kimenetét a második paraméterbe továbbítja! Írj egy olyan scriptet (atiranyit2.sh), amely az első paraméterben megadott parancsot végrehajtja és a kimenetét a második paraméterbe, a hibát pedig a harmadik paraméterben megadott fájlba továbbítja! #!/bin/bash $1 > $2 #!/bin/bash $1 > $2 2>$3
28
Szűrők Parancs kimenet egy másik parancs bemeneteként jelenik meg
Szűrő (| jel) cat nagyfile | more Fontosabb szűrők cut - sorok kiválasztott részeit írja ki tee - olvasás a standard bemenetről, írás a standard kimenetre és fájlokba sort - szövegfile sorainak rendezése uniq - egy rendezett fájlból kiszedi a duplikált sorokat tr - karakterek lecserélése, tömörítése és/vagy törlése wc - fájlokban található bájtok, szavak és sorok számát írja ki grep - mintához illeszkedő sorokat nyomtat
29
cut A cut program minden megadott FÁJL minden sorának a kiválasztott részeit írja ki a standard kimenetre Gyakori opciók -c KARAKTERLISTA Csak a KARAKTERLISTA által megadott pozícióban lévő karaktereket írja ki. -d ELVÁLASZTÓ Az -f opció által használt mezőelválasztót adja meg a ELVÁLASZTÓ első karaktere (alapértelmezésben a <TAB>) -f MEZŐLISTA Csak a MEZŐLISTA által felsorolt mezőket írja ki $echo a b cd | cut -f2 -d " " b $echo abcdef | cut -c 2,4 bd $echo ab cd ef | cut -f2 -d " " cd cat /etc/passwd | cut -f1 -d ":" |sort >felhasznalok Vágjuk ki a /etc/passwd állományból a felhasználók neveit és írjuk rendezett listában a sort szűrő segítségével egy állományba
30
tee a standard bemenetén kapott adatokat a standard kimenetre és valamennyi argumentumként kapott fájlba másolja. Ez akkor hasznos, ha az adatokat nemcsak a csővezetéken szeretnénk továbbítani, hanem szükségünk van egy másolatra is.
31
sort A sort parancs rendezi, összefűzi vagy összehasonlítja a megadott szövegfájlok, vagy ha nincs file megadva, a standard input minden sorát. Gyakori opciók -b : figyelmen kívül hagyja a mező elején levő szóközöket -r : fordított sorrendbe rendez -u : egyforma kulcsokból csak egyet vesz who | cut -f1 -d " " | tee felh.txt | sort -ru A bejelentkezett felhasználók listájából vágd ki csak a felhasználói neveket, amelyet a felh.txt állományban is tárolj el, a képernyőn viszont a fordítva rendezett, ismétlődést nem tartalmazó lista jelenjen meg!
32
uniq uniq kiírja az egyedi sorokat egy rendezett fájlból, és eldobja az egyezőket egy kivételével
33
tr tr átmásolja a standard bemenetet a standard kimenetre végrehajtva egyet a következő feladatok közül: cserél, és választhatóan tömöríti az eredményben az ismétlődő karaktereket tömöríti az ismétlődő karaktereket karaktereket töröl karaktereket töröl, majd tömöríti az eredményben az ismétlődő karaktereket. Gyakori opciók -d : törlés Gyakori osztálynevek: Alnum Betűk és számok alpha Betűk digit Számok lower Kisbetűk punct Írásjelek upper Nagybetűk
34
wc program bájtok, szavak és újsor-jelek számát számolja meg az argumentumként megadott fájlokban Gyakori opciók -c : csak a bájtok számát írja ki -l : csak a sorok számát írja ki -w : csak a szavak számát írja ki
35
grep a megnevezett bemeneti fájlokban a megadott mintához illeszkedő sorokat keres. reguláris kifejezések használhatók (pl. ^ a sor elejére illeszt) Gyakori opciók -i : kis és nagybetűket nem különböztet meg -w: csak önálló szóként találja meg -c: csak a sorok számát írja ki -n: sorok sorszámát is kiírja -v: azokat írja ki, amelyekre nem illeszkedik a minta
36
grep Hány q-val kezdődő azonosítójú felhasználó van?
cat /etc/passwd | grep ^q |wc -l Hány q-val kezdődő azonosítójú felhasználó van?
37
Feladatok Kérdezzük le a rendszer összes felhasználójának adatait a getent passwd parancs segítségével és tegyük bele felhasznalok.txt állományba. Hány felhasználóról kapunk információt? A felhasznalok.txt állományt felhasználva irassuk ki az összes felhasználó teljes nevét Ábécésorrendben ki az első 10 a felhasználók bejelentkezési neve szerint? Írjuk bele a torolt_felhasznalok.txt állományba a rendszerből ideiglenesen törölt felhasználók nevét! Segítség: az ideiglenesen törölt felhasználók a 666-os felhasználó-azonosítót kapják. getent passwd >felhasznalok.txt cat felhasznalok.txt |wc –l cat felhasznalok.txt |cut -f1 -d ":„ cat felhasznalok.txt |cut -f1 -d ":" |sort | head -n 10 (grep ':666:' < felhasznalok.txt | cut -f1 -d: > torolt_felhasznalok.txt)
38
Reguláris kifejezések
egy szövegmintákat leíró nyelvet jelentenek, segítségével rendkívül könnyen oldhatóak meg keresés, helyettesítés, általában szövegek feldolgozáshoz kötődő feladatok A reguláris kifejezésekkel a UNIX parancsaiban - történelmi okok miatt - legalább három változatban találkozunk. 1. alapszintű (basic) [expr, grep alapmód, sed alapmód] 2. POSIX bővített (extended) [egrep, sed –r, awk] 2. Perl kompatibilis - a Perl programozási nyelvben használatos kifejezések, mai változata a Perl 5-ös verziójában jelent meg
39
A reguláris kifejezéseket meghatározó szabályok
Egy egyedülálló karakter, amely nem újsor karakter, és nem a . * [ ] \ ^ $ karakterek egyike, önmagára illeszkedik. Ez azt jelenti, hogy ha a reguláris kifejezés egy a betű, akkor ez a vizsgált szövegben csakis egy darab a karakterre fog illeszkedni. A \c karakterpáros, ahol c egy látható karakter, a c karakterre illeszkedik a karakter literális értelmében. Tehet a \* illeszkedik a * -ra, a \\ pedig a \ -re. A . (pont) karakter egy olyan reguláris kifejezés, amelyik bármelyik (nem újsor) karakterre illeszkedik. Így pl. az ab. minta illeszkedik az aba, abb, abc, ..., abz, ab0, ... karaktersorokra. Ha e egy reguláris kifejezés, akkor e* egy olyan reguláris kifejezés, amely az e reguláris kifejezés 0 vagy többszöri előfordulását jelzi. Így az a* reguláris kifejezés illeszkedni fog az üres sztringre (hiszen abban zérószor szerepel az a karakter), valamint az a, aa, aaa, ... karakterláncokra.
40
A reguláris kifejezéseket meghatározó szabályok
A [ ] zárójelbe tett karaktersorozat illeszkedik az abban a pozícióban levő bármely, a zárójelben felsorolt karakterre. A karakterek felsorolására vonatkozó szabályok: kódjukat tekintve az egymás után következő karaktereket rövidíteni lehet a kötőjel használatával. Pl. 0-9a-z jelenti az összes számjegyet és az angol abc összes kisbetűjét. a nyitó zárójelet követő ^ jel a felsorolt karakterek tagadása. Pl. [^0-9] jelenti a bármely nem szám karaktert. a ] zárójel csak a felsorolás első tagja lehet a - karaktert a \- karakterpáros jelenti Két egymás után írt reguláris kifejezés szintén reguláris kifejezés. pl. [^0-9][0-9] kifejezés a nem szám karaktert követő szám karaktersorra illeszkedik. Két egymástól | jellel elválasztott reguláris kifejezés illeszkedik akár az egyik akár a másik kifejezésre. A ^ jel a sor elejére, a $ jel a sor végére illeszti a mintát.
41
Példa feladatok a reguláris kifejezésekhez
Felhasználói azonosítók lekérdezése: cat /etc/passwd | cut -f1 -d ":" Szűrjük le a q-val végződő azonosítójú felhasználókat … | grep q$ Hány felhasználó azonosítójában van benne a csa szöveg? … | grep csa |wc –l
42
Példa feladatok a reguláris kifejezésekhez
Adjuk meg azon azonosítókat, amelyekben szerepel az a betű, amelyet tetszőleges karakter követ, amely után az i betű szerepel, amely után tetszőleges karakter állhat, majd b karakter következik … | grep a.i.b Hány olyan azonosító van, amelyben szám szerepel … | grep [0-9] | wc –l Hány olyan azonosító van, amely számra végződik? … | grep [0-9]$ | wc -l
43
Példa feladatok a reguláris kifejezésekhez
Hány olyan azonosító van, amelyben szerepel kötőjel … | grep \- | wc –l Hány olyan azonosító van, amely z betűvel kezdődik, vagy z-vel végződik ... | grep "^z\|z$" | wc -l
44
Vezérlő szerkezetek
45
A Shell vezérlő szerkezetei
parancssori szerkezetek végrehajtásának sorrendjét nevezzük vezérlésnek. Erre a shell szintaxisa különböző, úgynevezett vezérlési szerkezetet használ.
46
Igaz/hamis feltétel a shell programozásban
A parancsok lefutásának sikerességéről a visszatérési érték (exit status) informál, amelyet a $? változó tartalmaz. Hibátlan lefutás esetén a visszatérített érték 0, míg hiba esetén eltér 0-tól
47
Kilépési kódok 0: Sikeres parancsvégrehajtás.
>0: Hiba történt a parancssor kiértékelésénél (akár az átirányításokban, behelyettesítésekben is lehet ez). 1-125: A program lefutott, de hibával lépett ki. 126: A program létezik, de nem lehetett végrehajtani (pl. nincs jogunk hozzá, vagy nem egy végrehajtható bináris kód). 127: A parancs nem létezik (nem lehetett a PATH elérési útjai szerint megtalálni) > 128: A program jelzéssel állt le (pl. ha a cat futása közben lenyomjuk a ^C -t, a program 130-at térít vissza). Megjegyzés: a 128 -as kód jelentése nincs standardizálva.
48
Az && , || és ! szerkezetek && az ÉS-nek, a || a VAGY-nak felel meg, míg a ! NEGÁLja az eredményt Az && szerkezet végrehajtja a parancssoron következő parancsot, amennyiben az előző lefutott parancs „hibátlanul" futott le, tehát igaz visszatérített értékkel zárult A || esetében viszont a második parancsot nincs értelme végrehajtani, ha az első jól futott le
49
Az && , || és ! szerkezetek Akár „ha, akkor” szerkezet is kialakítható
Az ! Operátornak egy jobb oldali parancs operandusa kell, hogy legyen
50
A test parancs Gyakran tesztelünk
állományok tulajdonságait (létezik-e, írható-e, olvasható-e, stb.) karakterláncokat (vagy változókat, amelyek karakterláncot tartalmaznak: létezik-e, mennyi az értéke) -számszerű értékeket (számokat tartalmazó karakterláncokat)
51
A test parancs Használata Gyakori opciók (fájlok tesztelése)
Test kifejezés [ kifejezés ] Gyakori opciók (fájlok tesztelése) -d file Igaz ha a file létezik és könyvtár. -e file Igaz ha a file létezik. -s file Igaz ha a file létezik és 0-nál nagyobb méretű -r file Igaz ha a file létezik és olvasható -w file Igaz ha a file létezik és írható. A kifejezés előtt és mögött is szóköz van!
52
A test parancs Gyakori opciók (karakterláncok tesztelése)
-z string Igaz ha a string 0 hosszúságú -n string Igaz ha a string nem 0 hosszúságú
53
A test parancs Logikai tesztek két test kifejezés között ! kif
Igaz ha kif hamis. kif1 -a kif2 Igaz ha kif1 és kif2 is igaz. (Logikai 'és'.) kif1 –o kif2 Igaz ha kif1 vagy kif2 igaz. (Logikai 'vagy'.)
54
A test parancs Számokat tartalmazó karakterláncok összehasonlítása
arg1 OP arg2 Az OP operátor valamelyik a következőkből -eq (egyenlő) -ne (nem egyenlő) -lt (kisebb) -gt (nagyobb) -ge (nagyobb, vagy egyenlő)
55
Az expr parancs Shell változók közti művelet elvégzésére szolgál, használata: expr kifejezés Fontosabb aritmetika és logikai kifejezések ARG1 | ARG2 ARG1 ha az nem 0 vagy null sztring, egyébként ARG2 ARG1 & ARG2 ARG1 ha egyik argumentum sem 0 vagy null sztring, másképp 0 ARG1 < ARG2 ARG1 kisebb mint ARG2 ARG1 <= ARG2 ARG1 kisebb vagy egyenlő ARG2 ARG1 = ARG2 ARG1 egyenlő ARG2 ARG1 != ARG2 ARG1 nem egyenlő ARG2 ARG1 >= ARG2 ARG1 nagyobb vagy egyenlő ARG2 ARG1 > ARG2 ARG1 nagyobb ARG2 ARG1 + ARG2 aritmetikai összeg: ARG1 + ARG2 ARG1 - ARG2 aritmetikai különbség ARG1 - ARG2 ARG1 * ARG2 aritmetikai szorzat ARG1 * ARG2 ARG1 / ARG2 aritmetikai osztás ARG1 / ARG2 ARG1 % ARG2 aritmetikai maradéka az ARG1 / ARG2-nek STRING : REGEXP mintaillesztés a STRING első karakterétől Vigyázni kell az olyan műveleti jelekre, amelyek shell metakarakterek is ( *,<,>,&,|) . Ezeket backslash jelöléssel kell használni. Pl. \*
56
Az expr parancs (példák)
$ expr 3 = 3 1 $ expr 3 = 2 0 $ expr 3 > 2 $ expr 3 \> 2 $ expr 2 * 6 expr: szintaktikai hiba $ expr 2 \* 6 12 Igaz Hamis Ez így átirányítás, és nem nagyobb reláció! Így már tényleg nagyobb relációról van szó. A * jel elé szintén kell a \ jel!
57
Az expr parancs (példák)
2+3 $ expr 2 +3 expr: szintaktikai hiba $ expr 2 + 3 5 $ $ a=$(expr 150 \* 231) $ echo $a $ expr 3 \| 4 3 $ expr 0 \| 4 4 $ expr 3 \& 4 $ expr 3 \& 0 0 $ expr 0 \& 4 Az üres helyet ki kell tennem! \ jelet kell használnom!
58
Aritmetikai számítások
Az expr használata sokszor kényelmetlen a Korn shell, valamint 2.04 verziótól kezdve a Bash is biztosít alternatívát egész számok kezelésére (hordozhatóság viszont problémás lehet!) Példa: valtozo=$(( aritmetikai műveletek )) $ a=5 $ b=$((a+2)); echo $b 7 $ b=$(($a+2)); echo $b $ x=$(( )); echo $x 28 $ x=$((22+6)); echo $x Szóköz használat itt nem szükséges a $ jelet nem kell változók előtt használni, de lehet. Kivételt képeznek a shell speciális változói. Pl. $1
59
Aritmetikai számítások
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 4 3 C nyelv operátorai használhatók.
60
Feltételes végrehajtás if szerkezettel
Megoldhatjuk, hogy egy bizonyos feltételtől függően egyik vagy másik parancssor legyen végrehajtva Használata if feltétel_parancs_sor then parancs_sor . . . elif feltétel_parancs_sor else fi if feltétel_parancs_sor then parancs_sor . . . else parancs_sor fi Az if vagy else ág a feltételes végrehajtásnál nem lehet üres (tehát valamit végre kell ott hajtani). Amennyiben a programozás során mégis üres ágat akarunk használni, a shell üres utasítását kell használnunk, a melyet a : szimbólummal hívunk meg.
61
If példák $ if [ 5 -gt 1 ] ; then echo nagyobb; fi; nagyobb
$ if [ 5 -gt 10 ] ; then echo nagyobb; else echo nem nagyobb;fi; nem nagyobb
62
If példa Mit csinál az alábbi script? #!/bin/bash
szoveg="Utolsó sor a fájl végére" filenev="1.txt” if [ -w "$filenev" ] then echo $szoveg >> $filenev else echo "$filenev" nem írható fi Példa a test parancs használatára if szerkezetben: ha a fájl írható a felhasználó számára, akkor írok egy sort a végére, másképp hibaüzenetet írok ki:
63
If példa Írjunk olyan scriptet cdd néven, amely belép a paraméterül átadott könyvtárba, ha az létezik és kiírja az „Aktuális könyvtár: könyvtárnév” szöveget, egyébként pedig a „Sajnálom, nincs ilyen könyvtár” üzenetet írja ki! #!/bin/bash if !(cd $1) 2>/dev/null then echo "Sajnálom, nincs ilyen könyvtár!" fi
64
Lehetséges megoldás #!/bin/bash if cd $1 2>/dev/null then echo Az aktuális könyvtár: $(pwd) else echo "Sajnálom, nincs ilyen könyvtár!" fi
65
Próbáljuk ki Jogosultság beállítás: chmod u+x cdd $ ./cdd nincs_ilyen
Sajnálom, nincs ilyen könyvtár! $ mkdir proba $ ./cdd proba Az aktuális könyvtár: /h/gipsz/proba $ pwd /h/gipsz/ Miért nem ugyanaz a könyvtár? A script egy új shell-ben hajtódik végre, ahogy az bezáródik, az előző aktuális könyvtár kerül beállításra. Megoldás? => source scriptnév vagy . script_név Ekkor az aktuális shell soronként olvassa be a file-t, es a hatás ugyanaz, mintha te gépelted volna be ezeket a sorokat,
66
Eredmény $ pwd /h/gipsz $ . cdd proba Az aktuális könyvtár: /h/gipsz/proba /h/gipsz/proba $ cd .. $ source cdd proba
67
A for ciklusok A for ciklus egy listán végez iterációt. A lista elemei az általunk használt legtöbb esetben karakterláncok. Használata for i do parancs_sor done for i in lista do parancs_sor done A parancs_sor -ban a $i változó használható, és sorra felveszi a lista elemeinek értékét. a $i változó a parancssor paraméterein iterál, tehát a változóban található sztringeket járja végig.
68
A for ciklusok (példák)
#!/bin/bash #for1.sh for i in abc def ghi do echo $i done $ bash for1.sh abc def ghi $
69
A for ciklusok (példák)
#!/bin/bash #for2.sh for i in $(seq 1 5) do echo $i done Ha pl. számokat akarunk végigjárni, akkor azokat a UNIX seq parancsával generálhatunk A seq parancs kiír egy számokból álló szekvenciát, a korlátokat és a lépésközt az argumentumokban lehet megadni. Az implicit lépés az 1. Pl. a seq hívás 1-től 10-ig írja ki a számokat, de csak minden másodikat. $ bash for2.sh $
70
A for ciklusok (példák)
#!/bin/bash #for3.sh for f in $( ls ) do echo $f done Itt a lista elemei az aktuális könyvtár elemei lesznek $ bash for3.sh 1.txt felh.txt for3.sh
71
A for ciklusok (példák)
A (( )) zárójeles szerkezetet is használhatjuk (ahogy a C nyelvben) for (( i=0; i<10; i++ )) do shell parancsok #ezekben használható a $i változó . . . done $ for (( i=1; i<=5; i++ )); do echo $i; done 1 2 3 4 5
72
A while és until ciklusok
A while illetve until ciklusok feltételét ugyanúgy állítjuk elő, mint az if szerkezetét. A while addig folytatja a ciklust míg feltétele igaz értékkel lép ki, az until pedig amíg a feltétel hamis. while feltétel_parancs_sor do parancs_sor . . . done until feltétel_parancs_sor do parancs_sor . . . done
73
While példa 1. Olvassunk addig szöveget a terminálról (read parancs), amíg a „vége” szót be nem gépeljük. $ bash while1.sh 1.sor 2.sor vége $ #!/bin/bash #while1.sh sor="" vege="vége" while [ "$sor" != "$vege" ] do read sor done
74
While példa 2. A While paranccsal használhatunk csővezetéket is.
#!/bin/bash # while2.sh cat '1.txt' | while read sor do echo $sor echo "***************" done $ bash while2.sh Egy, megérett a meggy *************** Kettő, csipkebokor vessző
75
While példa 3. Írjunk egy scriptet, amely megkérdezi, hogy „Mikor halt meg Petőfi Sándor?”, majd bekéri az adatot úgy, hogy látszik a próbálkozásunk száma is. Kilépni a kilép szó begépelésével lehessen. A helyes válasz gy.k.: 1849 $ bash while3.sh Mikor halt meg Petőfi Sándor? 1 . próbálkozás 1848 2 . próbálkozás 1849 1850 kilép $
76
While példa 3. (egyfajta megoldás)
#!/bin/bash x=0 y="" while [ "$y" != "1849" -a "$y" != "kilép" ] do echo "Mikor halt meg Petőfi Sándor?" x=$(( $x + 1 )) echo $x . próbálkozás; read y done
77
Until ciklus Az until ciklus akkor hasznos, ha valamilyen eseményt kell figyelni, és van egy változóm amelyik a ciklus végrehajtása közben, valamilyen esemény hatására kap értéket. until feltétel_parancs_sor do parancs_sor . . . done
78
Until példa 1. Írjunk egy scriptet, amely megkérdezi, hogy „Mikor született Neumann János”, majd bekéri az adatot úgy, hogy látszik a próbálkozásunk száma is. Kilépni a kilép szó begépelésével lehessen. A helyes válasz: 1903 $ bash until1.sh Mikor született Neumann János? 1 . próbálkozás 1900 2 . próbálkozás 1903 1911 kilép
79
Until példa 1. (egyfajta megoldás)
#!/bin/bash until [ "$y" = "1903" -o "$y" = "kilép" ] do echo "Mikor született Neumann János?" x=$(( $x + 1 )) echo $x . próbálkozás; read y done
80
Összehasonlítás While Until #!/bin/bash x=0 y=""
while [ "$y" != "1849" -a "$y" != "kilép" ] do echo "Mikor halt meg Petőfi Sándor?" x=$(( $x + 1 )) echo $x . próbálkozás; read y done #!/bin/bash x=0 y="" until [ "$y" = "1903" -o "$y" = "kilép" ] do echo "Mikor született Neumann János?" x=$(( $x + 1 )) echo $x . próbálkozás; read y done
81
Példa Írjuk 5-ször a képernyőre: Ismétlés a tudás anyja!
A feladatot valosítsuk meg a for, while és until ciklussal is! $ for i in $(seq 1 5); do echo "Ismétlés a tudás anyja"; done $ x=0; while [ $x -lt 5 ]; do echo Ismétlés a tudás anyja; x=$(( $x + 1 )) ;done; $ x=0; until [ $x -eq 5 ]; do echo Ismétlés a tudás anyja; x=$(( $x + 1 )) ;done;
82
A break és continue használata
A break megszakítja a ciklust ott ahol megjelenik (és a ciklus utáni parancson folytatja), a continue nem fejezi be a kurrens ciklust hanem a következő iterációra lép. Megjegyzendő, hogy a break használható többszintű ciklusból való teljes kilépésre, pl. a break 2 elhagy egy 2 szintes ciklust.
83
Continue példa (cont.sh)
Írjuk ki a 3-al nem osztható számokat 1 és 20 között! $ bash cont.sh A 3-al nem osztható számok 1-től 20-ig: #!/bin/bash hatar=20 #felső határ echo "A 3-al nem osztható számok 1-től 20-ig:" a=0 while [ $a -le "$hatar" ] do a=$(($a+1)) if [ $(expr $a % 3 ) -eq 0 ] then continue fi echo -n "$a " done echo
84
Break példa (break.sh) Készítsünk egy végtelen ciklust, amely 1-től kiírj a számokat. A ciklust szakítsuk meg 20 lépés után! $ bash break.sh Számok 1-től 20-ig: #!/bin/bash echo "Számok 1-től 20-ig:" while true do a=$(($a+1)) if [ $a -gt 20 ] then break fi echo -n "$a " done echo
85
Beágyazott ciklus és a break
#!/bin/bash #break2.sh for kulso in do echo -n "Csoport $kulso: " # for belso in echo -n "$belso" if [ "$belso" -eq 3 ] then break fi done echo $ bash break2.sh Csoport 1: 123 Csoport 2: 123 Csoport 3: 123 Csoport 4: 123 Csoport 5: 123
86
Beágyazott ciklus és a break (break 2 esetén)
#!/bin/bash #break2.sh for kulso in do echo -n "Csoport $kulso: „ # for belso in echo -n "$belso" if [ "$belso" -eq 3 ] then break 2 fi done echo $ bash break2.sh Csoport 1: 123$
87
A shift parancs A shift "eltolja" a parancssor argumentumait egy argumentummal balra. Ugyanakkor a $# változó értéke is változik, egyel csökken. Az alábbi példában a szkript kiír minden parancssori argumentumot, de úgy, hogy mindig a $1 változót írja ki. A shift pedig minden ciklusban átnevezi a $1,. . .,$9 speciális változókat, úgy hogy a megfelelő parancssori értékeknek egyel kisebb számjegy nevű változót rendel. #!/bin/bash while [ $# -gt 0 ] #amíg van még argumentum do echo A '$#' értéke: $# , a '$1' értéke: $1 shift done $ bash shift1.sh egy kettő három négy A $# értéke: 4 , a $1 értéke: egy A $# értéke: 3 , a $1 értéke: kettő A $# értéke: 2 , a $1 értéke: három A $# értéke: 1 , a $1 értéke: négy A shift -et paraméterrel is meg lehet hívni, olyankor a paraméternek megfelelő számmal forgatja el a parancssor argumentumait, tehát a shift 2 hívás kettővel.
88
Shift parancs Írjunk olyan scriptet (shift2.sh), amely a paramétereket a shift parancs segítségével párosával kiírja, közéjük = jelet rakva. $ bash shift2.sh egy one kettő two három three egy = one kettő = two három = three #!/bin/bash while [ $# -gt 0 ] #amíg van még argumentum do echo $1 = $2 shift 2 done
89
Kilépés a shell programból: az exit
A shell programokból az exit paranccsal lépünk ki, melynek egy egész számból álló paramétere van, ez lesz a szkript visszatérítési értéke. Ha jól, hiba nélkül fut le a programunk, ez az érték 0 kell legyen. Az alábbi példa leteszteli, hogy a programunknak van-e legalább egy paramétere. Ha nincs, hibával lép ki. #!/bin/bash #tesztelem, hogy a parancssor első paraméterének 0 -e a hossza if [ -z "$1" ] then echo legalább egy paraméter szükséges ! exit 1 fi # feldolgozás itt exit 0 $ bash exit1.sh legalább egy paraméter szükséges ! $ echo $? 1 $ bash exit1.sh 1 Ha elfelejtjük a program végéről az exit -et, az utolsó végrehajtott parancs által visszatérített érték marad a $? változóban.
90
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 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. case valtozó in minta1 ) parancsok ;; minta2 ) parancsok ;; . . . mintaN ) parancsok ;; esac
91
A case szerkezet A karakterek 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 abc pontosan abc-re illeszkedik * bármire illeszkedik ?bc bármi az első karakter pozíción, és utána pontosan ab ab|cd ab vagy cd láncokra illeszkedik
92
case példa 1 #!/bin/bash # case1.sh echo -n "Adj meg egy állat nevet:"
read ALLAT echo -n "Ennek az állatnak " case $ALLAT in ló | kutya | macska) echo -n "négy";; tyúk | majom ) echo -n "két";; *) echo -n "nem tudom hogy hány";; esac echo " lába van." exit 0 $ bash case1.sh Adj meg egy állat nevet: ló Ennek az állatnak négy lába van. Adj meg egy állat nevet: elefánt Ennek az állatnak nem tudom hogy hány lába van.
93
Case feladat (case2.sh) Írjunk futtat parancsot, ami a paraméterektől függően más és más programot futtat! Ha –d a paraméter, akkor futtassuk a date parancsot, ha –w akkor írjuk ki a bejelentkezett felhasználók nevét, ha –l akkor a könyvtár tartalmát írja ki! Ha nem egy paraméterrel, vagy rossz paraméterrel futtatjuk a programot, írjon ki mini segítséget! case valtozó in minta1 ) parancsok ;; minta2 ) parancsok ;; . . . mintaN ) parancsok ;; esac case $1 in -d ) date;; -w ) who;; -l ) ls -al;; *) echo "A használható paraméterek: -d, -w, -l";; esac
94
Megoldás #!/bin/bash case $1 in -d ) date;; -w ) who;; -l ) ls -al;;
*) echo "A használható paraméterek: -d, -w, -l";; esac
95
A select szerkezet A select szerkezetet kis interaktív programok esetében használjuk. 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 valtozó értéke felveszi a listából kiválasztott karakterlánc értékét, és ezt fel lehet használni valamilyen parancs végrehajtásra. select valtozo in lista do parancsok done
96
Select példa $ bash select1.sh Melyik parancsot akarja végrehajtani?
#!/bin/bash #a PS3 értékét ajánlatos valamilyen ismerős prompt-ra cserélni PS3='>>' echo Melyik parancsot akarja végrehajtani? select valtozo in date who ls vége do echo $valtozo echo a '$REPLY' változó értéke: "$REPLY" case $REPLY in 1 ) date;; 2 ) who;; 3 ) ls -al;; 4 ) break;; esac done $ bash select1.sh Melyik parancsot akarja végrehajtani? 1) date 2) who 3) ls 4) vége >>1 date a $REPLY változó értéke: 1 2009. okt. 8., csütörtök, CEST >>4 vége a $REPLY változó értéke: 4
97
Gyakorló feladatok
98
osszeg.sh Adjuk össze a számokat szam1-től szam2-ig az expr és seq parancsot használva! (osszeg.sh) Az átadott két paraméter azt határozza meg, hogy mettől meddig kell a számokat összeadni Ha nem két paraméter van, jelenjen meg a következő szöveg: A script használata: osszeg.sh szam1 szam2 $ bash osszeg.sh A script használata: osszeg.sh szam1 szam2 $ bash osszeg.sh 3 11 =63
99
Lehetséges megoldás #!/bin/bash #ellenorzom, hogy 2 argumentum van-e
if [ $# -ne 2 ] then echo A script használata: osszeg.sh szam1 szam2 exit 1 fi #a szamok generalasara a seq parancsot fogom hasznalni #a seg egy szekvenciat general n tol m-g #mielott inditom, letrehozom a sum valtozot 0 ertekkel sum=0 for i in $( seq $1 $2 ) do #hozzaadom a $sum -hoz a $i-t sum=$( expr $sum + $i ) echo -n $i if [ $i -ne $2 ] then echo -n + else echo -n = done echo -n $sum echo exit 0
100
Szoveges.sh 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 [] zárójelben a sorban levő karakterek számát (szoveges.sh ). Ha a script nem kap paramétert, akkor jelenjen meg a következő szöveg: A script használata: szoveges.sh fájlnév $ bash szoveges.sh szoveges.txt 1 [15] : ez az elso sor 2 [8] : 3 [14] : ez a harmadik $ bash szoveges.sh A script használata: szoveges.sh fájlnév
101
Lehetséges megoldás #!/bin/bash #csak egy parameter if [ $# -ne 1 ]
then echo A script használata: szoveges.sh fájlnév exit 1 fi #kezdeti ertek sorszam=0 cat $1 | while read sor do #a sorszamot kulon szamolom sorszam=$( expr $sorszam + 1 ) #a karakterek kiszamitasa a wc-vel karakterek=$( echo $sor | wc -c ) #kiirom echo $sorszam [$karakterek] ':' $sor #a sorokat ugy olvasom, hogy a while #ciklusba iranyitom a bemeneti allomanyt Done exit 0
102
Faktoriális számítás Írjunk shell script programot (fakt.sh), ami kiszámolja a paraméterül adott szám faktoriálisát! ./fakt.sh 4 24 ./fakt.sh 4 24
103
Faktoriális számítás (egy megoldás)
Írjunk shell script programot (fakt.sh), ami kiszámolja a paraméterül adott szám faktoriálisát! #!/bin/bash i=1 fakt=1 while [ $i -le $1 ] do fakt=`expr $fakt \* $i` i=$(( $i + 1 )) done echo $fakt exit 0 Vissza
104
Faktoriális számítás 2. Az alábbi kódot módosítsuk úgy, hogy ha nem egy paramétert adott meg a felhasználó, jelenjen meg a „A script használata: fakt.sh szám” szöveg #!/bin/bash i=1 fakt=1 while [ $i -le $1 ] do fakt=`expr $fakt \* $i` i=$(( $i + 1 )) done echo $fakt exit 0 if [ $# -ne 1 ] then echo A script használata: fakt.sh szám exit 1 fi Vissza
105
Faktoriális számítás 3. ./fakt3.sh 4 1*2*3*4=24
#!/bin/bash #csak egy parameter if [ $# -ne 1 ] then echo A script használata: fakt.sh szám exit 1 fi i=1 fakt=1 while [ $i -le $1 ] do fakt=`expr $fakt \* $i` echo -n $i i=$(( $i + 1 )) if [ $i -gt $1 ] echo -n "=" else echo -n "*" done echo $fakt exit 0 Fejlesszük tovább a scriptet úgy, hogy ne csak a végeredmény, hanem a számítás módja is látszódjon! ./fakt3.sh 4 1*2*3*4=24 Vissza
106
Szó olvasás Írjunk script programot (szoolvas.sh), ami szavakat olvas be egészen addig, míg a vége szót nem írjuk be, majd sorba rendezve kiírja a képernyőre azokat! (Használjunk ideiglenes fájlt!) ./szoolvas.sh Add meg a szavakat! körte alma banán vége A rendezett sorozat:
107
Szó olvasás (egy megoldás)
Írjunk script programot (szoolvas.sh), ami szavakat olvas be egészen addig, míg a vége szót nem írjuk be, majd sorba rendezve kiírja a képernyőre azokat! (Használjunk ideiglenes fájlt!) echo Add meg a szavakat! read a until [ $a = vége ] do echo $a >>ideigl.txt done echo A rendezett sorozat: cat ideigl.txt | sort rm ideigl.txt exit 0 Vissza
108
Szumma Írjunk programot (szumma.sh), amelyik a paraméterül kapott számokat összeadja és az összeget a szabványos kimenetre írja! A paraméterül megadott számok helyett megadhatjuk a –help kapcsolót, aminek hatására írjunk ki rövid ismertetőt a programról!
109
Szumma (egy megoldás) Írjunk programot (szumma.sh), amelyik a paraméterül kapott számokat összeadja és az összeget a szabványos kimenetre írja! A paraméterül megadott számok helyett megadhatjuk a –help kapcsolót, aminek hatására írjunk ki rövid ismertetőt a programról! #!/bin/bash if [ "$1" = "-help" ] then echo "Ez a program a paraméterül átadott számok összegét adja meg." else osszeg=0 for i in do osszeg=`expr $osszeg + $i` done echo Az összeg: $osszeg fi exit 0 Vissza
110
Szumma szűrőként Módosítsuk a szumma.sh programot úgy, hogy szűrőként is lehessen használni! (szum.sh) $ echo | bash szum.sh Az összeg: 16
111
Szumma szűrőként (egy megoldás)
Módosítsuk a szumma.sh programot úgy, hogy szűrőként is lehessen használni! (szum.sh) #!/bin/bash if [ $# -eq 0 ] then for i in `cat` do osszeg=`expr $osszeg + $i` done echo Az összeg: $osszeg else if [ "$1" = "-help" ] echo "Ez a program a paraméterül átadott számok összegét adja meg." else osszeg=0 for i in fi exit 0 Vissza
112
Számjegyösszeg (szjossz.sh)
Írjuk ki egy beolvasott szám számjegyeinek összegét!
113
Számjegyösszeg Írjuk ki egy beolvasott szám számjegyeinek összegét! (szamjegyosszeg.sh) #!/bin/bash read szam osszeg=0 while test $szam -gt 0 do maradek=`expr $szam % 10` osszeg=`expr $osszeg + $maradek` szam=`expr $szam / 10` done echo "A szamjegyek osszege:" echo $osszeg Vissza
114
küldés Írj olyan shell scriptet ( .sh), amely a paraméterként megadott nevet behelyettesíti az alábbi szövegbe, és azt automatikusan elküldi a második paraméterben megadott címre. Kedves NÉV! Sikerült megoldanom a feladatot.
115
E-mail küldés (egy megoldás)
Írj olyan shell scriptet ( .sh), amely a paraméterként megadott nevet behelyettesíti az alábbi szövegbe, és azt automatikusan elküldi a második paraméterben megadott címre. Kedves NÉV! Sikerült megoldanom a feladatot. #!/bin/bash cat<<Vege >ideigl.txt Kedves $1! Sikerült megoldanom a feladatot! Vege mail $2<ideigl.txt rm ideigl.txt exit 0 Vissza
116
Bejelentkezés Egy háttérben futtatható scripttel (login.sh) fél percenként ellenőrizzük, hogy a paraméterként megadott felhasználó bejelentkezett-e a rendszerbe! Ha igen, érkezzen számunkra levél: a felhasználó neve kerüljön a tárgyba, és a terminálazonosítója a levéltörzsbe.
117
Bejelentkezés(egy megoldás)
Egy háttérben futtatható scripttel (login.sh) fél percenként ellenőrizzük, hogy a paraméterként megadott felhasználó bejelentkezett-e a rendszerbe! Ha igen, érkezzen számunkra levél: a felhasználó neve kerüljön a tárgyba, és a terminálazonosítója a levéltörzsbe. #!/bin/bash # hasznalat: login.sh usernev & until test 0 -eq 1 do for i in `who | cut -d" " -f1` if test "$i" = "$1" then echo `who | grep "$i" | cut -c 10-16` | mail -s "$i be van jelentkezve" fi done sleep 30 Vissza
118
Köszönöm a figyelmet!
Hasonló előadás
© 2024 SlidePlayer.hu Inc.
All rights reserved.