![]() Veikimo valdymas Unix skriptuose Šis straipsnelis pratęsia puslapį Unix komandinės eilutė Įvadiniame straipsnelyje pateikėme pagrindines žinias apie komandinės eilutės interpretatorius bei pačią komandinę eilutę. Tad, kilus neaiškumams (pvz., apie komandinės eilutės interpretatorius), pasitikslinkite tą puslapį. O čia toliau tęsime pamokas apie programavimą Unix aplinkoje. Visi čia pateikiami pavyzdžiai buvo patikrinti Aix 6.1.8.0 aplinkoje (tačiau, iš esmės, jie turėtų tikti ir Linux). Orientavomes, kad jie tiktų Bourne interpretatoriui (sh), - tačiau, jei pavyzdžiai arba aptariami klausimai skirti kitiems interpretatoriams (paprastai, tai bash), tai atskirai nurodoma. Vykdymo eigos valdymas Unix apvalkalai logines reikšmes traktuoja atvirkščiai jiems 0 tiesa (true), o ne 0
melas (false). Tai susiję su tuo, kad Unix komandos gražina 0, jei komanda buvo įvykdyta
teisingai, ir klaidos kodą, jei buvo klaidų. Šis įvykdymo kodas gražinamas į apvalkalo aplinkos kintamąjį
Operacijos pabičiui gali būt įvykdytos tik naudojant sintaksę su skliaustais - ((išraiška)) , pvz., echo $((1&0)) # - reikšmė 0 ((1&0)) echo $? # - pateikiama 1 (false) echo $((13&7)) # - reikšmė 5 ((13&7)) echo $? # - pateikiama 0 (true) && ir || atveju antroji išraiška neskaičiuojama, jei pirmosios pakanka rezultatu nustatyti. Pvz., ((1 != 1)) || echo netiesa ((1 != 2)) && echo tiesa Bus išvesta netiesa tiesanes pirmosios išraiškos nepakako išraiškos teisingumui nustatyti ir buvo vykdyta antrosios dalys (su echo). Sąlyginio vykdymo valdymas If sakinio formatas: if išraiška1 then veiksmai1 elif išraiška2 then veiksmai2 else veiksmai3 fi elif ir else dalys nėra privalomos ir gali būti praleistos. elif dalių gali būti kelios. Pvz. if ((1==1)) then echo 1 elif ((1==2)) then echo 2 elif ((3==3)) then echo 3 else echo 4 fi Galima naudoti patikros (()), [[]] ir [] konstruktus...
Operacijos skirstomos į tris grupes:
Su teksto eilutėmis; Su eilutėmis yra šios operacijos: Su skaičiais: Pvz., typeset -i x=12 if [[ $x -eq 11 ]] then echo lygu fi Su failais: Pvz., if [ -r data.txt ] && [ -s data.txt ] then echo "Failas data.txt egzistuoja, leistina jį skaityti ir jo dydis ne nulinis" fi if [ -e data.txt ] then echo "Failas data.txt egzistuoja" else touch data.txt # sukuriamas tuščias failas fi Ciklai Kita svarbi galimybė yra ciklinės operacijos. Tam tikslui Unix apvalkalas numato for, while ir until konstrukcijas. Visose jose veiksmai apgaubiami do ir done raktiniais žodžiais, pvz., typeset -i x=0 while [$x -le 3] do let x++ echo $x done Rezultatas: 1 2 3 4 until ciklas beveik identiškas, tik jo užbaigimo sąlyga priešinga while until ciklas baigiamas, kai sąlyga yra patenkinama. Pvz. (tam pačiam rezultatui): typeset -i x=0 until [$x -gt 3] do let x++ echo $x done Tuo tarpu for ciklui reikalingas elementų sąrašas, pvz., for item in a b c do echo $item done Rezultatas: a b c set vienas du trys for var do echo $var done Rezultatas: vienas du trys suma=0 for item in 1 2 3 4 do ((suma += $item)) done echo Suma=$suma Rezultatas:
Ciklo viduj galimi papildomi valdymo sakiniai: suma=0 for item in 1 2 3 4 do ((suma += $item)) if [ $suma -ge 4 ]; then break; fi done echo Suma=$suma Atsakymas:
for item in 1 2 3 4 5 6 do if [ $item <4 ] || [ $item == 6 ]; then continue; fi echo $item done Rezultatas: 4 5 Keli išsišakojimai case esac sakinys suteikia galimybę patikrinti reikšmę su keliais šablonais. Viduje nurodomi šablonai, besibaigiantys ), su kuriais tikrinama nurodyta reikšmė. Po šablonų eina sakiniai, vykdomi tuo atveju, jei tenkinamas šablonas. Veiksmų pabaiga žymi du kabliataškiai (;;). Reikšmė su šablonu tikrinama nuosekliai kol bus rastas ją tenkinantis šablonas, - įvykdžius veiksmus po to šablono, tikrinimas nutraukiamas Pavyzdžiui: c="bet kas" case $c in tikra) echo "tikras tekstas";; *) echo "kita: $c";; esac Bus patektas toks rezultatas (nes buvo tenkintas šablinas *: Pastaba: bash interpretatoriuje šabloną galite pradėti atidarančiu skliaustu (, pvz., c="tikra" case $c in (tikra) echo "tikras tekstas";; (*) echo "kita: $c";; esac Šįkart atsakymas bus: select sakinys sukuria ciklą panašų į while, kai vartotojui išvedami pasirinkimai. Jis gali nurodyti pasirinkimo numerį, - ir pasirinkimo tekstas priskiriamas nurodytam kintamajam. Ciklas su siūlymu įvesti pasirinkimą kartojamas tol, kol neįvykdoma komanda break. Pvz., select var in Taip Ne Baigti do echo $var case $var in Taip) echo "bus kartojama";; Ne) echo "bus kartojama";; Baigti) echo "bus baigiama"; break;; *) echo "Nežinomas pasirinkimas";; esac done Čia pateikiamas vykdymo protokolas, kai buvo pasirinkti (įvesti) variantai 1, 4 ir 3. 1) Taip 2) Ne 3) Baigti #? 1 Taip bus kartojama #? 4 Taigi, pradžioje išvedamas pasirinkimų sąrašas, tada siūloma įvesti pasirinkimą (#?). Įvedus 1, išvedamas pasirinkimo tekstas (Taip) ir bus kartojama (veiksmas prie Taip). Tada cikle vėl siūloma įvesti pasirinkimą (#?), o įvedus 4, pasirinkimo teksto nėra (nes nėra atitikmens pasirinkimuose), o išvedamas tekstas Nežinomas pasirinkimas (pagal šablono * veiksmus). Vėl ciklas ir įvedus 3 pranešama bus baigiama ir ciklas baigia darbą, nes įvykdoma komanda break (esanti veiksmuose prie Ne šablono). Vartotojo reikšmių įvedimui naudojama komanda read, kuri reikšmes priskiria nurodytiems
kintamiesiems, pvz., Įvedame: Tada $pavadinimas įgauna reikšmę Stalas, o $kiekis 5.
Įvedame:
Pastaba: jei komandoje read nenurodomas joks kintamasis, reikšmė priskiriama
kintamajam Įvedus:
Leistini read parametrai: Pvz.: Papildomos bash galimybės bash interpretatorius suteikia daug papildomų galimybių... Riestiniai skliaustai { ... } yra vienas išplėtimų, įtraukiančių visas kableliais atskirtas išvardintas simbolių eilutes. Sutikęs tokią konstrukciją interpretatorius suformuoja eilutę su visomis galimomis kombinacijomis riestinių skliaustų vietoje Pvz., Rezultatas: o ${} sintaksė suteikia ir daugiau galimybių.
Pvz., tokia forma leidžia atlikti pakeitimus tekste: Jei kintamasis yra * arba @ - operacija (šalinimo ar ištraukimo) atliekama visiems poziciniams parametrams. ${kintamasis:pradžia} eilutės galas pradedant nurodyta pozicija (skaičiuojant nuo 0); Ilgis privalo būti teigiamas, tačiau pradžia gali būti ir neigiamas skaičius tai rodo, kad poslinkis skaičiuojamas nuo eilutės pabaigos Šis pavyzdys pateikia kintamųjų pavadinimus, tenkinančius nurodytą šabloną: manoVardas="Vardenis Pavardenis"; manoAdresas="Gatvė Pagatvė 123"; manoUgis=180; echo ${!mano*} Rezultatas: Funkcijos Galimybes labai išplečia funkcijos pakartotinai panaudojamas kodas, gražinantis reikšmę, ir iškviečiamas iš kitų skriptų. Čia pateikiame vidurkio paskaičiavimo funkciją ir jos iškvietimo pavyzdį. Jame pailiustruojama, kad funkcijos irgi gali dirbti su poziciniais parametrais. #!/bin/bash vidurkis () { viso=0 for var do ((viso += var)) done return $((viso/$#)) } # end vidurkis vidurkis 5 10 6 echo "Vidurkis (5 10 6): $?" Rezultatas: Antrame pavyzdyje pailiustruosime eilutės teksto pakeitimą mažosiomis raidėmis: #!/bin/bash LW () { local ix=0 for v in "$@" do rv[$ix]=$(echo $v | tr '[A-Z]' '[a-z]') ((ix += 1)) done echo "${rv[@]}" } # end LW read -p "Šalis: " s lsalis=$(LW $s) echo $lsalis Vykdymo pavyzdys: Funkcija gali gražinti tik skaitinę reikšmę. Tad panaudota konstrukcija $(cmd) sintaksė, leidžianti išvedimo srauto reikšmę priskirti kintamajam. O ${rv[@]} konstrukcija yra ekvivalentiška ${rv[*]}, tačiau geriau tvarkosi su tarpais (apie tai žr. >>>>>) Pavyzdžiuose pateiktos procedūros yra bendrojo pobūdžio, tad jos gali būti surašytos į atskirą failą, o
kituose skriptuose tuo failus prijungti source arba . komandomis, pvz.,
Kintamieji, aprašyti funkcijoje su typeset, declare ar local komandomis galioja tik toje procedūroje. Jei tokiu pat vardu yra už funkcijos ribų, jo reikšmės nebus paveiktos. Naudingi pavyzdžiai a) kaip patikrinti, ar katalogas yra tuščias?
Pvz., jei katalogas nėra tuščias, pašalinti jame esančius failus: work_DIR=darbinis [ "$(ls -A $work_DIR)" ] && rm $work_DIR/* b) Kaip suskaičiuoti failus veiksniame kataloge? Tai galima atlikti komanda: Pirmosios (ls) komandos parametras yra vienetas (1) , reiškiantis, kad reikia failus vardinti po vieną eilutėje. c) Kaip paskaičiuoti skripto vykdymo laiką? Žemiau pateikiamame pavyzdyje vykdymo trukmė paskaičiuojama milisekundėmis (tai nurodo
%3N begin=$(date +"%s%3N") # [ reikalingi veiksmai ] end=$(date +"%s%3N") df=$(($end-$begin)) echo $df d) JSON duomenų apdorojimas Visuotinai išplitus JSON formatui, atsiranda poreikis apdoroti šio formato duomenis. Pvz., taip duomenis gražina daugelis servisų ir reikia patikrinti jų atsakymą. Pirmiausia, rekomenduoju įsidiegti patogų JSON parserį. Siūlau jq, kurį galima parsisiųsti iš čia. Tai tarsi sed (žr. apie jo naudojimą) analogas JSON duomenims. Faktiškai, jq - tai filtras: programa paima įėjimo duomenis, juos patikrina su filtru ir išveda
filtro atsijotus duomenis. Tad jos formatas: Paprasčiausias jos panaudojimas (ir naudingas gražesniam JSON struktūros išvedimui) ką gavau,
tą gražinau:
Dabar pereikime prie konkretesnio pavyzdžio. Tarkim kuriam kažkokį objektą ir tam skirtas servisas
gražina jo ID, pvz., formatu ats=`echo {"id"="567"}` IDVal=`echo $ats | jq ".id" | tr -d '"'` if [[ $IDVal == +([0-9]) ]] ; then objSukurtas=1; else objSukurtas=0; IDVal=0; fi echo $IDVal Mūsų pavyzdžio rezultatas turi būti: Komentarai pavyzdžiui: Ankstesnės "Advanced HTML" skyrelio temos: | |