Már az egyik előző részben megismertük a felhasználói adatmegadás, azaz adatbevitel egyik módját: a parancssori argumentumokat, azaz a kapcsolókat. Ez egy hasznos megoldás, hiszen a script indításakor megadhatjuk a paramétereket. Egy nagy hibája van, ami sok esetben kellemetlen. Az indításkor adhatjuk meg őket, így futásidőben már nincs lehetőség adatbevitelre. Bár sok argumentumot megadhatunk, de kérdéses, hogy a felhasználó örömmel látná, hogy fél tucatnyi, lehetőleg jó hosszú ilyen argumentumot várunk el tőle. Szerintem már négy, teljes elérési utat is tartalmazó fájlnév megadás is elrettenti a scriptedtől az átlagembert :). Így érdemes a scriptet interaktívvá tenni, ami jelen esetben csak annyit jelent, hogy ha kell, akkor a futásidőben is bekérhessen a script parancssorból egy-egy adatot a felhasználótól. A parancssorból? Miért is nem valami grafikus panelben, hiszen az a szebb, korrektebb és a felhasználók jobban szeretik. Mert első körben érdemes a parancssorból bekérni adatokat, hiszen ha bármelyik grafikusabb megoldást választjuk, ahhoz elvárás pár telepített program (pld. kdialog). Így nem leszünk kitéve annak a kellemetlen helyzetnek, hogy a script hibajelet ad, hogy nincs valami feltelepítve, hanem csak a mindenképp rendelkezésre álló eszközzel dolgozik.
Általánosságban érdemes a bekért adatokat, válaszokat változókban tárolni.
A legegyszerűbb megoldás az interaktív scriptekben a read használata.
Alapszerkezete a következő:
read var_1
Azaz nem túl bonyolult. Kiíratsz egy kérdést, majd read, és a változó neve, és már készen is vagyunk.
Egyszerű példa:
#!/bin/bash # Mi a neved? echo Szia! Ki van a gépnél? read name echo Üdv $name!
Figyelj rá, hogy read name és nincs közte egyenlőségjel. Hibaforrás lehet, hiszen eddig a változók megadásánál az egyenlőségjelet használtuk. Bár szerintem logikus, de mindenképp figyeljünk a változó nevére. Egyedi legyen, és egy változó nevét egy célra használd. A script logikája az, ha megadsz egy változót, akkor az addig viseli azt az értéke, amíg másra át nem állítod.
Egy példa:
name=Kata echo $name echo ---------- echo Szia! Ki van a gépnél? read name echo Üdv $name!
Látod, hogy a name változó értéke a read, az új megadás után megváltozott. Ez sok esetben jó, ha attól a ponttól a name változónak más értéket akar adni, de zavaró lehet, ha nem. Így ha a scriptben nincs szükség konkrétan a változó értékének a változtatására, akkor érdemesebb eltérő neveket adni.
A read viselkedését jól szabályozhatjuk. Két általánosan használt opció a -p, amely lehetővé teszi a prompt, azaz a kérdés megadását, és az -s, amely a bemenetet elhallgattatja, azaz nem jelenik meg a begépelt szöveg. Az alapvető megoldást a következő példa mutat:
read -p 'Username: ' uservar read -sp 'Password: ' passvar echo echo Köszi $uservar, már el is loptam az adataidat!
Boncoljuk fel a fenti scriptet.
-p ‘Username: ‘ Egyszerűbb a -p kapcsoló utáni szöveget, a kérdést megadni, mint egy echo, vagy egyéb megoldással. Itt azért használjuk a ‘Username: ‘, azaz az idézőjeles megoldást, mert a kérdés nem csak egy szóból állhat, és a space, azaz a szóközök esetén elég furán jelenítheti meg a szöveget, ha nem mondod meg neki, hogy egy blokk az egész, és egybe írja ki. Próbáld ki! Illetve érdemes a kérdés után egy space-t betenni, mert akkor a válasz beírása egy üres karakter után kezdődik, ami jobban néz ki. Kicsike kis trükk, de ha már megírsz valamit, akkor erre is figyelj. Próbáld ki mindegyik verziót!
read -sp ‘Password: ‘ passvar Az s hozzátételével már nem fog látszani a beírt szöveg. Ez nagyon hasznos a jelszavak megadásánál. Bár most írjuk, és nem végrajtunk scriptet, de jó lenne, ha felvennéd azt a szokást, ha egy script, amit kaptál bekéri az adataidat, akkor előbb belenézel, majd azután futtatod. Kicsi, de nem nulla az esélye az adatlopásnak egy letöltött pársoros scriptnél, de…
Több adat bekérése read-dal
Ahogy láttad, több adatot bekérhetünk egymás után is. A read fel lett készítve arra is, hogy több adatot egy sorban is be tudjon kérni. Ez nagyobb figyelmet kíván.
A z alap szerkezete nagyon egyszerű:
read var_1 var_2 var_3
A példa szerint már egyértelmű leszűrni
echo A teljes neved: read csalad kereszt echo $csalad echo $kereszt
Nem túl nehéz igaz? A szerkezettel több problémám van, de az egyik legnagyobb, hogy hm… user szinten időnként vannak „problémák” a megértésben, így nem biztos, hogy a kért sorrendben adják meg a paramétereket. Így ha nem a várt információ kerül az adott változóba, akkor az a későbbiekben gondot jelenthet. Jobb sok esetben, ha szépen sorban kéred be a változók értékét.
A read elvégzi a beírást, és megosztja azt a szóközönként. Az első elem ezután az első változó nevéhez, a második elem a második változó névhez lesz hozzárendelve és így tovább. Ha több elem van, mint a változó neve, akkor a fennmaradó összes elemeket hozzáadja az utolsó változó névhez. Ha kevesebb elem van, mint a változónevek, akkor a fennmaradó változónevek üresek lesznek.
A STDIN, azaz a standard bemenet
A bash scriptek nem csak interaktívan, a felhasználótól kapott adatokkal tudnak dolgozni, hanem a STDIN-ről is fogadhatnak adatfolyamot. Ez a legtöbb esetben egy fájl, amit beolvastatunk és feldolgozunk. Illetve egy parancs kimenete is lehet a bemenő adatsor. Nagyon praktikus megoldás!
A megoldást már ismerjük, hiszen a piep témát több helyen is érintettük.
Az alap, legegyszerűbb megoldás, ha egy szöveges fájlt olvastatunk be, majd azt feldolgoztatjuk. Készíts egy olyan szöveges fájlt, ami
Fred apples 20 July 4
Susy oranges 5 July 7
Mark watermelons 12 July 10
Terry peaches 7 July 15
négy sort tartalmaz. A neve: salesdata.txt.
Majd készítsük el a sciptet:
e
cho Eladási adatok: echo =========== echo cat /dev/stdin | cut -d' ' -f 2,3 | sort
Bár nem témánk, és máshogy is megoldható, de a fenti három echo sort érdemes megfigyelni, mert egy egyszerű formázott kimenetet ad:
Eladási adatok:
===========
Ami sokkal jobban néz ki, mint egy sima felírat, hogy Eladási adatok: majd az adatsor.
Majd
cat salesdata.txt | ./teszt.sh
és látjuk is az eredményt.
Én a fenti megoldást nem nagyon használom, de mivel ismerni illő, írtam. Én jobban kedvelem ha argumentumként adjuk meg a kezelendő fájlt, és a scriptben olvastatom be a cat-tal.
A mai rész lényege: ha kell, akkor a read-dal bekérhetünk adatokat, infókat a scriptbe a felhasználótól. Ez jó megoldás, a maga viszonylag korlátos módján. Ha pedig a felhasználótól olyan adat kell, amire pár lehetőséget előre definiálni tudunk, akkor a select megoldást is választhatjuk.