shell-programmeerimine, protsessid Käsuinterpretaatorid shell: "koorik" vs. tuum + Käsuinterpretaator + Programmeerimiskeel - "skriptid", stsenaariumid, käsufailid, ... Bourne shell - sh -> ksh (Korn shell) Vaadeldavad teemad: + Muutujad (s.h. sisseehitatud muutujad) + Erisümbolid + Sisendi ja väljundi(te) suunamine + Protsessid ja käskude grupeerimine + .profile + Juhtimisstruktuurid ja shell-programmide koostamine C shell - csh Lisanduvad: + ajalugu, history + makrokäsud, alias + arvulised muutujad ja massiivid + automaatselt täidetavad käsufailid .login .cshrc .logout + süntaksierinevused programmeerimisel Bourne shell. Muutujad, käsk echo Ainult sõnemuutujad (string). + Kasutajamuutujad (user variables) - kasutaja saab luua, kirjutada, lugeda, kustutada, eksportida. Saab luua ka kasutajaväärtusi (read only user variables). + Shell-muutujad (shell variables) - sisseehitatud, kasutaja saab lugeda ja muuta. + Shell-väärtused (Read only shell variables) - kasutaja saab ainult lugeda. Käsurea laiendamisel kasutame testimiseks käsku echo: echo parameeter Väljastatakse parameeter, kus kõik erisümbolid (metamärgid) on asendatud vastavalt nende tähendusele. Näit: echo * Töö muutujatega nimi=jaanus - muutuja loomine ja väärtustamine, tühikuid ei tohi olla echo $nimi - väärtuse vaatamine Näide. Tühikutega väärtus tekst='mitu s6na' Erinevate stringieraldajate mõju: echo $tekst mitu s6na echo '$tekst' $tekst echo "$tekst" mitu s6na echo \$tekst $tekst Standardseid shell-muutujaid: $0 - väljakutsuva programmi nimi $1 kuni $9 - käsurea parameetrid (ükshaaval) $* - käsurea parameetrid (kõik koos) $# - käsurea parameetrite arv (stringina) Käsuga shift shell-programmis saab tagumisi parameetreid koha võrra ettepoole nihutada (esimene parameeter "kaob ära"). Käsk set võimaldab programmeerijal $1 kuni $9 väärtusi muuta: set esimene teine kolmas $HOME - kodukataloogi nimi $PATH - otsimistee (eraldajaks koolon) $PS1 - primaarne viip $PS2 - sekundaarne viip Sisendi ja väljundi suunamine Bourne shell korral * > 1> - standardväljund faili * < - standardsisend failist * | - konveier, toru, pipe * >> - standardväljund vanale (võib-olla) failile sappa * 2> - veaväljund faili * 2>&1 - veaväljund standardväljundiga samasse kohta * << - sisend shell-programmist Näit. ls > listing more < tekst ls -al | more ls >> listingud Näide shell-programm andmed (õigused r-x vajalik anda) grep -i $1 <<+ # plussmärk lõputunnuseks Jaan Tatikas Liivi 2 Juhan Puravik Kalevi 3 + Pöördumine: andmed Kalevi Tulemus: Juhan Puravik Kalevi 3 C-shell korral * > - sama, mis Bourne shell korral, aga puudub analoog 2> tarvis; samuti ei kirjutata üldjuhul olemasolevat faili üle * >! - lubab olemasoleva faili üle kirjutada * >& - standardväljund ja veaväljund suunatakse koos * |& - ühine toru Näit. ( käsk > failinimi ) >& /dev/null Standardväljund saadetakse faili, veaväljund "musta auku" Käsk tee tee [-i] [-a] failinimi ... Kopeerida standardsisend standardväljundisse ja faili(desse) Näit. ls | tee protokoll -i - ignoreerida katkestusi -a - lisada faili(de)le, mitte üle kirjutada Sisendi lugemine Bourne shell-programmis read muutuja ... Näit. echo 'Sisesta nimi: \c' read nimi muu echo 'Sisestasid: ' $nimi $muu \c keelab ülemineku uuele reale. Unix - protsessid Sarnaselt failisüsteemile moodustavad ka protsessid hierarhia - alamprotsessid, ülemprotsess, juur ... Käsu täitmisel käivitatakse alamprotsess ning üldjuhul ülemprotsess "uinub" ja jääb ootama alamprotsessi lõppemist. Igal protsessil süsteemis on unikaalne number (PID). $$ - aktiivse protsessi PID $! - viimase fooniülesande PID Protsess annab alati naasmiskoodi (return code, exit status), 0=true=OK, muu=false. Seda koodi saab kontrollida, shell-programmides ka ise seada. $? - viimati lõpetanud protsessi naasmiskood exit kood - käsk shell-programmi lõpetamiseks etteantud naasmiskoodiga & käsu lõpus - ülemprotsess ei "uinu", vaid käsk täidetakse foonil (background) ja ülemprotsess töötab edasi. käsk1 ; käsk2 ; ... ; käskN - käskude järjestikune täitmine käsk1 | käsk2 | ... | käskN - konveier e. toru, käskude järjestikune täitmine, kusjuures eelmise väljund on järgmise sisendiks käsk1 & käsk2 & ... & käskN - sõltumatute käskude paralleelne täitmine, viip naaseb, kui käskN on lõpetanud käsk1 && käsk2 - kui käsk1 andis tõrke, siis käsk2 ei täideta käsk1 || käsk2 - kui käsk1 lõppes edukalt, siis käsk2 ei täideta Sulgude abil saab käske grupeerida - iga grupi täitmiseks luuakse eraldi shell-protsess: ( a ; b ) & ( c ; d ) & Muutujad on vaikimisi antud protsessi jaoks lokaalsed, alamprotsessidele väärtuste edasiandmiseks tuleb muutuja eksportida. Luuakse uus koopia (by value), s.t. väärtust tagasi anda ei saa. Protsessil on keskkond. Kasutajaprotsessidel on üldjuhul määratud omanik ning nn. kontrolliv terminaal - see tuleneb protsesside hierarhiast (millise getty alluvuses). Käsud tööks protsessidega * ps - analoog käsule ls protsesside jaoks * jobs - C shell, näidata taustatööde loetelu * kill - tappa protsess või taustatöö * wait - oodata taustprotsesside lõppu * nice - prioriteedi määramine taustprotsessile * sleep - paus, protsessi "uinutamine" etteantud ajaks * nohup - jätkata antud tööd ka pärast seansi lõppu * at - täita käsufail etteantud ajal * bg - C shell, viia töö taustale * fg - C shell, tuua töö esiplaanile ps [-efal] [-u user] - System V ps [-axgl] - BSD jobs - C-shell, antud kasutaja tööd, numbrid %-ga kill [-signaal] PID -9 kindel tapmine kill [-signaal] %job - C shell korral wait [PID] nice [-n] käsurida n = 1 .. 10 , mida suurem, seda madalam prioriteet sleep sekundid nohup käsurida at aeg päev [week] käsufail vt. ka crontab bg %job - C shell, käivitada taustatööna fg %job - C shell, tuua fookusesse Unix - programmeerimine Bourne shellis * test * if ... then ... elif ... then ... else ... fi * for ... in ... do ... done * while ... do ... done * until ... do ... done * case ... in ... ) ... ;; esac * break * continue Käsk test Juhtimiskonstruktsioonides kasutatakse hargnemiseks lõpetuskoode, sageli just käsu test lõpetuskoodi (0 - true, muu - false). Käsk test väärtustab etteantud loogilise avaldise. Käsu test asemel kasutatakse vahel kantsulge. test avaldis Avaldis koosneb tigimus(t)est, mida saab kombineerida tehete -a (and), -o (or), ! (not) ja sulgude \( ... \) abil. Konkreetsed tingimused on seotud stringide, täisarvude ja failidega. Käsuga test kontrollitavaid tingimusi: string - stringi pikkus suurem nullist -n string - stringi pikkus suurem nullist -z string - stringi pikkus null string1 = string2 - stringid võrdsed string1 != string2 - stringid erinevad täisarv -eq täisarv - arvud võrdsed (analoogilised veel -gt -ge -le -lt -ne ) -r wxfd failinimi - tingimused faili kohta (read, write, execute, plain file, directory) -s failinimi - fail leidub ja on pikem kui null baiti Hargnemine tingimus(t)e järgi if lõpetuskood then käsud [ [ elif lõpetuskood then käsud ... ] else käsud ] fi Näide. Kolme sõna võrdlemine: echo 'Sona1: \c' ; read sona1 echo 'Sona2: \c' ; read sona2 echo 'Sona3: \c' ; read sona3 if (test "$sona1" = "$sona2" -a "$sona2" = "$sona3" ) then echo `Koik vordsed' elif ( test "$sona1" = "$sona2" ) then echo 'Sona1 = Sona2' elif ( test "$sona1" = "$sona3" ) then echo 'Sona1 = Sona3' elif ( test "$sona2" = "$sona3" ) then echo 'Sona2 = Sona3' else echo 'Koik erinevad' fi Jadatsükkel Vaikimisi üle $1, $2, .... for tsükliindeks [ in väärtushulk ] do käsud done Näit. for paev in e t k n r l p do echo $paev done Jätkamistingimusega tsükkel while lõpetuskood do käsud done Näide. Jada 0123456789 trükkimine: arv=0 # stringmuutuja while ( test "$arv" -lt "10" ) # arvude võrdlus do echo "$arv\c" arv=`expr $arv + 1` # eritahendus done echo Lõpetamistingimusega tsükkel until lõpetuskood do käsud done Valikukäsk case string in [ näidis ) käsud ;; ... ] esac Näidises võib kasutada * ? [string] ja alternatiivide eraldajat | Näit. echo 'Kas lopetan? \c' read sumbol case $sumbol in [yY]* | [jJ]*) echo 'Lopetan' ;; [nN]* | [eE]*) echo 'Ei lopeta' ;; *) echo 'Ei saanud aru' ;; esac Tsükli katkestamine (for-, while-, until-): break Tsüklisammu katkestamine: continue C shell Ajalugu - history Teatud hulk viimati sisestatud käsuridu on võimalik meeles pidada ja uuesti kasutada (tcsh korral interaktiivselt). set history = 30 - 30 rida meelde history - kuvada ajalugu !! - täita viimane käsk !25 - täita käsk nr. 25 ajaloost !-3 - täita tagant kolmas käsk Sünonüümi loomine - alias alias nimi sisu - makromäärang unalias nimi - tühistamine alias ls ls -al - defineerime ls ümber ls - uus def. \ls - vana def. langkriipsuga unalias ls - tühistame aliase C shell - muutujaid $argv $cdpath $history $home $path $prompt $shell $status $noclobber - kaitseb juhusliku ülekirjutamise vastu (suunamismärkidele panna ! sappa) set - lokaalse sõnemuutuja loomine @ - lokaalse arvmuutuja loomine setenv - keskkonnamuutuja seadmine, analoog Bourne shelli ekspordile, näit. setenv PATH /usr/openwin/bin:$PATH unset - muutuja hävitamine Massiivid ja arvmuutujad set colors = ( red green blue ) echo $colors red green blue echo $colors[1] red echo $colors[2-3] green blue echo $#colors 3 (elem. arv) echo $?colors 0 (ON olemas) @ count = 3 @ count++ C süntaksiga avaldised echo $count 4 On olemas ka arvmassiivid, mille loomiseks vajalik käsk set . Väärtuse omistamisel panna avaldis ümarsulgudesse. Tingimused failide kohta ( 0 = true ): -e failinimi - fail on olemas -f failinimi - on tavaline fail -d failinimi - on kataloog -o failinimi - kuulub mulle -r failinimi (-w, -x) - mul on vastav õigus Märkusi C shelli kasutamise juurde #!interpretaator käsufaili alguses annab selle faili täitmiseks antud interpretaatorile: näit. #!/bin/sh kui on tarvis (C-shellist) pöörduda Bourne shell programmi poole ~/.login ~/.logout ja ~/.cshrc (csh) ~/.login ~/.logout ja ~/.tcshrc (tcsh) Puudub vajadus test- ja expr-käskude järele, juhtimiskonstruktsioonide süntaks on erinev ja on lisatud uusi if ( avaldis ) lihtkäsk if ( ... ) then ... else if ( ...) then ... else ... endif foreach tsükliindeks ( väärtused ) käsud end goto märgend while ( avaldis ) käsud end switch ( string ) [ case näidis : käsud breaksw ... ] [ default: käsud breaksw ] endsw Avaldiste süntaks erinev (C-laadne) Sisendi lugemine klaviatuurilt erinev.