A 4. oldal tartalma
Folytatás
Az előző oldalon megismerkedtünk az asszociatív tömbökkel, most folytatjuk néhány általánosan mindegyik tömbtípussal kivitelezhető megoldással.
Tömbök exportálása
A a Bash jelenleg nem támogatja a tömbök exportálását, ezért saját megoldásra lehet szükségünk, ha például más scriptekből is el szeretnénk tudni érni a korábban deklarált tömbjeinket.
Első körben nézzük meg, hogy mi történik, ha simán exportálunk egy tömböt és egy normál változót a parancssorból:
declare -A tomb=([elso]="első" [masodik]="második elem")
valtozo="Sima string változó"
export tomb
export valtozo
Ezután ha futtatjuk az export parancsot:
export
akkor itt bent van a string változónk és még a tömbünk is, mivel ugyanabban a névtérben vagyunk:
[...] declare -Ax tomb=([elso]="első" [masodik]="második elem" ) declare -x valtozo="Sima string változó"
Ez eddig jó, de ha egy shell scriptben futtatjuk az export parancsot:
1 2 3 #!/bin/bash export
[...] declare -x valtozo="Sima string változó"
Akkor már eltűnik a listából a tömbünk, és csak a sima változó "élte túl" az exportot, mivel a script normál futtatásakor egy sub-shellben fut le, és annak a névterébe már nem került át a tömb exportunk csak a normál változónk.
Ha viszont nem a megszokott módon futtatjuk az iménti scriptet, hanem source-oljuk a "." használatával:
. ./scriptfile_neve
[...] declare -Ax tomb=([elso]="első" [masodik]="második elem" ) declare -x valtozo="Sima string változó"
Akkor ismét "visszakapjuk" a tömböt is. Ez pedig azért van, mert a source-oláskor a script nem sub-shellben fut le, hanem ugyanabban a shell-ben és annak névtérben, ahonnan végrehajtották a source-t, azaz a mostani esetben a parancssoréban, ahol deklaráltuk és exportáltuk a tömböt és a sima változót. Ezért ilyenkor bent vannak a létrehozott változók az exportban. Így kerülnek betöltésre például a különböző indítófájlok, mint például a .bash_profile, .bashrc, stb is.
Tehát az eddigiek alapján elmondható, hogy a normál név -> érték alapú változók exportálhatók a globális névtérbe, amiket aztán a sub-shell-ben is el lehet érni, azonban a tömböket nem lehet exportálni, azok csak a saját névtérben maradva érhetők el.
Időnként pedig szükség lehet rá, hogy egy meglévő tömböt el tudjunk érni egy lefuttatott shell scriptben is. Például amit a .bash_profile fájlunkban hoztunk létre, vagy akár a parancssorból. Erre van pár megoldás, ezek közül az egyiket fogjuk most kipróbálni.
Készítünk két scriptet a teszt kényelmesebb végrahajtásáért. Az egyiket source-olással fogjuk indítani, tehát olyan, mintha a .bash_profile vagy .bashrc fájlunkba tettük volna a tartalmát, vagy akár begépeltük volna azt a parancssorba. A másik fájlt pedig rendesen fogjuk futtatni, mint bármilyen más shell scriptet, amik ilyenkor egy subshell-ben kerülnek lefuttatásra.
Az egyik legyen mondjuk a.sh, a másik pedig b.sh
Az elsőbe tegyünk bele két tömb deklarációt: Egy indexelt és egy asszociatív tömböt, hogy lássuk mindkettővel a működést, valamint a végén lévő két sort:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #!/bin/bash # Indexelt tömb létrehozása declare -a tomb1=(első második harmadik) # Asszociatív tömb létrehozása declare -A tomb2=( [elso]="Első" [masodik]="Második" [harmadik]="Harmadik" ) export tomb1_serialized=$(declare -p tomb1) export tomb2_serialized=$(declare -p tomb2)
Itt a végén lévő kettő sor fogja működtetni az egészet, ami a következőt csinálja:
A declare -p <változó neve> parancs visszaadja a megadott változó deklarációs sorát, azaz azt a parancssort, amivel létre lehet hozni pontosan ugyanazt a tartalmú változót. Tömbök eseténél az összes kulcsot és értéket beleértve. Tulajdonképpen serializáljuk a tömböt egy karakterláncba, csak itt a kapott karakterlánc kimenetben maga a létrehozó parancs is benne van, ami egyébként most még jól is fog jönni.
A korábban létrehozott tömbünkkel például ezt adja ki:
declare -Ax tomb=([elso]="első" [masodik]="második elem" )
Ez itt most azért jó, mert a tömbökön lefuttatva kapunk egy-egy sort, amit egy sima string változóban is tárolhatunk. Ezt a kimenetet pedig egy $() burkolóval kiolvassuk egy másik változóba, amit string-ként már tudunk exportálni. Mindezt a fenti elméletekre alapozva tesszük, miszerint csak a normál változókat lehet exportálni a globális névtérbe, azaz a parancssorunk névterébe, míg a tömböket nem.
Ha most a "." segítségével source-oljuk a fenti fájlunkat:
. ./a.sh
Akkor lefutnak a benne lévő deklarációk és az exportok is a futtatás helyének névterében. Tehát ha most kiadunk egy export parancsot,
export
akkor a következőt láthatjuk a lista végén:
[...] declare -Ax tomb=([elso]="első" [masodik]="második elem" ) declare -x tomb1_serialized="declare -a tomb1=([0]=\"első\" [1]=\"második\" [2]=\"harmadik\")" declare -x tomb2_serialized="declare -A tomb2=([elso]=\"Első\" [masodik]=\"Második\" [harmadik]=\"Harmadik\" )" declare -x valtozo="Sima string változó"
Itt megtaláljuk a sorok között a fentebb létrehozott "tomb" és "valtozo" nevű változóinkat is, de ami a lényeg, hogy a két új serializált tömbünk is megvan, amiben benne van az összes kulcs és érték, ráadásul az idézőjelek is szépen escape-elve vannak, tehát készen állnak a string-ként történő szállításra, felhasználásra.
Most érdekességképpen ha lefuttatjuk azt a fájlunkat, amiben csak az export parancs volt, akkor a következőt fogjuk látni:
[...] declare -x tomb1_serialized="declare -a tomb1=([0]=\"első\" [1]=\"második\" [2]=\"harmadik\")" declare -x tomb2_serialized="declare -A tomb2=([elso]=\"Első\" [masodik]=\"Második\" [harmadik]=\"Harmadik\" )" declare -x valtozo="Sima string változó"
Pontosan amire számítottunk: Eltűnt a tömb deklarációnk, és megmaradt a három string alapú válrozó deklarációja.
Ezek alapján tehát összeállítjuk a másik parancsfájlunkat, amit "b.sh" néven nevezünk el, és beletesszük a következőket:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #!/bin/bash eval $tomb1_serialized eval $tomb2_serialized # Innentől már tudjuk használni az eredeti tömb változóinkat. echo "tomb1 indexelt tömb kilistázása:" for i in "${!tomb1[@]}"; do echo "$i: ${tomb1[$i]}" done echo echo "tomb2 asszociatív tömb kilistázása:" for i in "${!tomb2[@]}"; do echo "$i: ${tomb2[$i]}" done
Futtathatóvá tesszük a chmod +x paranccsal majd futtatjuk. A kimenetében pedig ezt kapjuk:
tomb1 indexelt tömb kilistázása: 0: első 1: második 2: harmadik tomb2 asszociatív tömb kilistázása: elso: Első masodik: Második harmadik: Harmadik
Ezzel a módszerrel tehát felhasználhatjuk a korábban a globális névtérben létrehozott tömb változóinkat a futtatott shell scriptjeinkben is.
Konklúzió
Ebben a hosszú leírásban megismerkedtünk a shell scriptekben használatos tömbökkel és azok kezelésével. Amint láthattuk, elég sok mindenre lehet használni a Bash tömbjeit, amikkel rugalmasabb scripteket állíthatunk elő. Ezeken kívül természetesen még sok mindent lehetne írni a tömbökről, ezért igyekeztem összeszedni a legfontosabb részeket, amiket a hétköznapokban is fel tudunk használni a programozás során. Remélem sikerült használható leírást összeállítani, ami segítségére lehet azoknak, akik most tanulmányozzák ezt a témát.
Lapozó
- A hozzászóláshoz regisztráció és bejelentkezés szükséges
- 171 megtekintés