C-10 C SHELL, BOURNE SHELL A KORN SHELL Obsah Predmluva ................................................... 2 1. Co je shell ? ............................................... 3 2. Funkce shellu ............................................... 3 2.1 Cteni povelu ................................................ 4 2.2 Substituce .................................................. 5 2.2.1 Substituce promennych ....................................... 6 2.2.2 Povelova substituce ......................................... 9 2.2.3 Generovani jmen souboru (metaznaky) ......................... 9 2.2.4 Vlnovkova (tilda) substituce a alternativni povely (aliasy) 10 2.3 Presmerovani standardnich souboru .......................... 11 2.4 Vyhledani povelu a jeho provedeni .......................... 12 2.4.1 Vyhledani povelu ........................................... 12 2.4.2 Provedeni povelu ........................................... 13 2.5 Rizeni uzivatelova prostredi ............................... 14 2.6 Ulozeni a zpristupneni predchozich povelu .................. 16 2.7 Rizeni procesu na pozadi ................................... 17 3. Poradi akci pri provadeni povelu ........................... 19 4. Modifikace povelove radky .................................. 20 4.1 Modifikatory povelove radky ................................ 20 4.2 Uvozovkovy aparat a povel eval ............................. 21 5. Pocitacova relace .......................................... 23 6. Shellovske programy ........................................ 24 6.1 Typy shellovskych programu ................................. 24 6.2 Proc psat shellovske programy ? ............................ 26 6.3 Prostredky shellovskych programu ........................... 27 7. Shellovske scenare ......................................... 29 7.1 Vytvoreni shellovskeho scenare ............................. 29 7.2 Dokumentace shellovskeho scenare ........................... 30 7.3 Provedeni shellovskeho scenare ............................. 31 8. Predavani parametru shellovskym scenarum ................... 33 8.1 Pozicni parametry .......................................... 34 8.2 Povel shift ................................................ 34 9. Vstup/vystup ............................................... 35 9.1 Vstup ...................................................... 36 9.2 Vystup ..................................................... 36 10. Vystupni stav a shellovska rozhodnuti ...................... 37 10.1 Nastaveni vystupniho stavu ve scenarich .................... 38 10.2 Vyhodnocovani logickych vyrazu a aritmetika ................ 39 11. Prostredky pro rizeni programu ............................. 41 11.1 Konstrukce pro rozhodnuti .................................. 42 11.1.1 Konstrukce if .............................................. 42 11.1.2 Konstrukce case (Bourne/Korn shell) ........................ 43 11.1.3 Konstrukce switch (C shell) ................................ 44 11.2 Konstrukce pro programove cykly ............................ 45 11.2.1 Konstrukce while ........................................... 46 11.2.2 Konstrukce until (Bourn/Korn shell) ........................ 47 11.2.3 Konstrukce for (Bourne/Korn shell) ......................... 47 11.2.4 Konstrukce foreach (C shell) ............................... 49 11.3 Konstrukce select pro programovani menu (Korn shell) ....... 49 12. Prostredky pro zajisteni bezpecneho provadeni scenaru ...... 51 12.1 Prostredky pro zpracovani chyb ............................. 51 12.2 Ladici prostredky .......................................... 54 12.2.1 Shellovske volby pri ladeni ................................ 55 12.2.2 Nastaveni v povelu trap .................................... 56 13. Co ma Korn shell navic oproti Bourne shellu ................ 57 14. Literatura ................................................. 62 Predmluva Tato prirucka je dalsi z prirucek rady C urcene pro uzivatele po- citace Cray Y-MP EL, vydanych Strediskem automatizace a vypocetni techniky (SAVT) Fyzikalniho ustavu AV CR. Tato rada informuje na uvod- ni urovni o problematice prekladu, vektorizace a optimalizace fortran- skych programu a jejich ladeni, o textovych editorech a o operacnim systemu UNICOS. Predkladana prirucka, jejimz autorem je A. Cejchan, navazuje na prirucku C-6: Operacni system UNICOS [1] a C-9: Sluzby UNICOSu [2] od tehoz autora. Protoze je vsak venovana vyhradne shel- lum, ktere jsou dostupne i na jinych unixovych pocitacich, neni jeji pouziti omezeno vyhradne na pocitac Cray. Prirucky jsou k dispozici u operatorek postupne tak, jak budou vydavany. Obsah techto prirucek je dostupny i v "on-line" tvaru na obrazovce, a to na pracovnich stanicich Sun jako soucast informacniho systemu www (World Wide Web), ktery umoznuje pohodlne prohlizeni ruznych dokumentu v siti Internet. System se spousti povelem www v radkovem modu nebo povelem xmosaic v grafickem modu. Prirucky SAVT na- jdete v nabidce pod heslem Fyzikalni ustav. Aktualni verze prirucky ve forme vystupniho souboru z Chi-Writeru 3 je pristupna vsem uzivatelum site prostrednictvim ftp na pocitaci ftp.fzu.cz po zalogovani jako anonymous (jako heslo napisete vasi e- mailovou adresu). Doporucene parametry pro tisk na laserovou tiskarnu z Chi-Writeru 3 jsou Margin Offset: 13, Pitch: Elite, Quality: Firmwa- re. V tistenem textu pouzivame az na drobne vyjimky nasledujici kon- venci pro typ pisma: to, co pise uzivatel na klavesnici, je znazorneno tucnym pismem (bold), metavyrazy, za nez je treba dosadit konkretni hodnotu, jsou psany ve scriptu, odezva pocitace je napsana kurzivou (italics). Nove zavadene pojmy a vetsinou i nazvy jednotlivych souboru v textu jsou psany rovnez kurzivou. Chceme tyto prirucky poskytnout uzivatelum v co nejkratsim case, a tak predpokladame, ze jejich obsah dozna zmen v jejich dalsich vyda- nich na zaklade postupne ziskavanych zkusenosti. Uvitame proto vsechny vase pripominky jak k obsahu, tak k forme techto informaci. Muzete po- uzit e-mail na adresu office@fzu.cz nebo primo na autora prislusne prirucky. 1. Co je shell ? Shell je program, ktery slouzi jako vase povelove rozhrani k ope- racnimu systemu. Pokud jste prihlaseni do systemu (uvedli jste sve uzivatelske oznaceni a heslo), shell interpretuje a provadi povely, ktere jste pocitaci zadali. Protoze shell neni operacni system, ale prostredek pro vase spojeni s nim, muze existovat (a take existuje) techto prostredku vice nez jeden. UNICOS podporuje tri siroce uzivane shelly: Bourne shell (s nazvem sh), C shell (csh) a Korn shell (ksh). Bourne shell je puvodni shell systemu UNIX vyvinuty v AT&T s Bell Laboratories, nazev nese po svem autorovi, Stevenu Bourneovi. C shell pochazi z BSD UNIXu. Nazev dostal vzhledem k podobnosti svych progra- movacich prostredku jazyku C. Take Korn shell byl vyvinut v AT&T jako naslednik Bourne shellu a take on dostal nazev po svem autorovi, Davi- du Kornovi. Kazdy uzivatel v UNICOSu ma tzv. login shell, ktery se mu spusti po prihlaseni do systemu. Tento login shell je nastaven systemovym ad- ministratorem; na pocitaci Cray je jim C shell, o cemz se lze presved- cit zapsanim povelu ps: cray101% ps PID TTY TIME COMMAND 4567 p001 0:01 csh J-- (csh je login shell) 4592 p001 0:00 ps cray102% Poznamka: V dalsim textu budeme pouzivat promptu tvaru "crayn% " (n je prirozene cislo) v C shellu (ve vyse uvedenem prikladu byly podoby promptu postupne cray101% a cray102%) a promptu "$" v Bourne a Korn shellu. V prikladech tak na prvni pohled poznate, jakemu shellu jsou povely predkladany ke zpracovani. (Znak $ je i implicitnim promptem v Bourne a Korn shellu, v C shellu je implicitnim promptem znak %.) Sa- mozrejme i v Bourne nebo Korn shellu nemusite zustat u implicitniho promptu; podrobneji viz kap. 13. 2. Funkce shellu Shell v UNICOSu slouzi nekolika hlavnim funkcim. Ackoli kazdy z jednotlivych shellu dostupnych v UNICOSu ma sve specificke prostredky, vsechny tri shelly nicmene zabezpecuji tyto nasledujici funkce: Cteni povelu Kazdy shell muze cist povely interaktivne (z uzivatelova termina- lu) nebo ze souboru. Soubor obsahujici povely, ktere ma shell precist, se nazyva shellovsky scenar (shell script). Substituce Shelly provadeji substituce urcitych konstrukci na povelove rad- ce. Typickym prikladem je substituce metaznaku ve jmenu souboru, ale existuji i mnohe jine substituce. Presmerovani standardnich souboru Presmerovani umoznuje povelum, aby cetly ze souboru nebo z vystu- pu jinych povelu (tzv. "roura") misto cteni z klavesnice a zapisovaly do souboru nebo do vstupu jinych povelu misto zapisu na obrazovku. Vyhledani povelu a jeho provedeni Po precteni a zpracovani povelove radky musi shell nalezt vlastni povel, ktery muze byt napr. vestaveny v shellu nebo to muze byt prove- ditelny soubor nekde v systemu souboru. Jakmile je povel nalezen, shell jej vykona (napr. spustenim programu). Rizeni uzivatelova prostredi Nastaveni promennych jako TERM, HOME apod. po prihlaseni do sys- temu poskytuje uzivateli uzitecne uzivatelovo prostredi (login envi- ronment). Tyto promenne se nazyvaji promenne prostredi (environment variables) a jsou nastaveny shellem. Uzivatel ma vsak moznost jejich hodnotu behem dalsi prace zmenit. Poskytnuti programovaciho rozhrani Programovaci prostredky shellu, jako jsou konstrukce if-then- else, while apod. poskytuji moznost vykonani automatickeho rozhodnuti a rizeni v uzivatelskem scenari (skriptu). Dva dalsi dulezite a uzitecne prostredky poskytuji Korn a C shell: Ulozeni a zpristupneni predchozich povelu Korn shell vam umoznuje zpristupneni, modifikaci a opakovane pro- vedeni vasich drivejsich povelu. C shell poskytuje specialni znaky, pomoci nichz provadi substituce v predchozich povelech za stejnym uce- lem jako Korn shell. Rizeni procesu na pozadi Prostredek "rizeni ulohy" v Korn a C shellu vam umoznuje mit ne- kolik povelu aktivnich a dostupnych v kteremkoliv okamziku. S timto prostredkem muzete premistovat procesy z pozadi do popredi a naopak. 2.1 Cteni povelu Jednou ze zakladnich funkci kazdeho shellu je cteni povelu zada- vanych uzivatelem. Tyto povely jsou pak interpretovany a provedeny. Shell muze cist povely dvema zpusoby. Interaktivni shell cte povely, jak byly zadany z klavesnice (cteni a provedeni povelu interaktivne), scenarovy shell cte povely ze souboru (znameho pod oznacenim shellov- sky scenar). Priklad: Mejme v adresari bin shellovsky scenar ps_scr, jehoz pristupove pravo pro provedeni (x) je povoleno, takze scenar muze byt proveden jako povel. Tento scenar obsahuje dve radky; na prvni je zvo- len scenarovy shell, na druhe je povel ps, ktery zobrazuje krome jine- ho i jmeno povelu pro kazdy bezici proces v relaci. Povsimnete si, ze login shell (v tomto pripade C shell) ma cislo procesu (PID) 65019. Scenar muzete spustit zapsanim jeho jmena jako povel. Kdyz scenar be- zi, scenarovy shell precte a vykona povel ps. V tomto okamziku muzete videt, ze jsou pritomny shelly dva: interaktivni shell (PID=65019) a scenarovy shell (PID=65389). Interaktivni shell precetl a vykonal po- vely ls, cat a ps, a take bin/ps_scr. Scenarovy shell precetl a vyko- nal povel ps, ktery je v shellovskem scenari bin/ps_scr: cray110% ls -FC bin ps_scr* cray111% cat bin/ps_scr #! /bin/csh ps cray112% ps PID TTY TIME COMMAND 65019 p010 0:01 csh (interaktivni shell) 65326 p010 0:00 ps cray113% bin/ps_scr PID TTY TIME COMMAND 65019 p010 0:01 csh (interaktivni shell) 65392 p010 0:00 ps 65389 p010 0:00 csh (scenarovy shell) cray114% 2.2 Substituce Kazdy shell interpretuje mnozinu specialnich znaku, ktere umoznuji pestrost substituci v povelove radce. Vsechny tyto substituce vykonava shell mezi prectenim povelu a jeho provedenim. Nasledujici substituce se vyskytuji ve vsech shellech: Substituce promennych Jestlize shell objevi odkaz na promennou, coz je znak dolaru ($) nasledovany jmenem promenne (tedy napr. $TERM), prelozi tento odkaz na hodnotu prislusne promenne. Jestlize hodnota promenne TERM je xterm, pak bude povelova radka obsahovat slovo xterm misto odkazu $TERM. Pro spravne urceni jmena promenne muzete pouzit dvojici slozenych zavorek ({ a }). Na povelove radce tedy dochazi pri substituci promennych k teto zmene: $TERM [---L xterm ${TERM}0 [---L xterm0 Povelova substituce Shell provede oddelene povely uzavrene v obracenych apostrofech (`povel`) a prelozi kazdy takovy retezec do vystupu prislusneho povelu. Napriklad: `ls | wc -l` [---L 19 Vystup z teto roury udava pocet souboru v pracovnim adresari, ktere nejsou zneviditelnene. Necht je takovych souboru devatenact. Proto po- velova radka, se kterou shell prave pracuje, obsahuje po povelove sub- stituci cislo 19 misto retezce `ls | wc -l` Generovani jmen souboru (metaznaky) Shell nahradi vzor pro jmena souboru, ktery obsahuje metaznaky, seznamem jmen vsech souboru, ktera tomuto vzoru vyhovuji. Napriklad: o*.f [---L opice.f olej.f o7.f .p* [---L .profile a?.o [---L ab.o a1.o le[dmn].f [---L led.f lem.f len.f le[a-e].f [---L lea.f leb.f led.f lee.f Nasledujici substituce poskytuji pouze Korn a C shell: Vlnovkova (tilda) substituce Shell rozvine znak vlnovky (tilda) (~) do absolutni cesty k vase- mu domovskemu adresari, kdykoli se tento znak objevi jako parametr ne- bo na zacatku cesty k souboru. V Bourne shellu muzete dosahnout tohoto efektu pouzitim odkazu na promennou HOME, tedy $HOME. Jestlize je pou- zito vyrazu ~uzivatelske_oznaceni, shell tento vyraz rozvine do abso- lutni cesty k domovskemu adresari uzivatelskeho_oznaceni. Bourne shell obdobnou notaci nema. Pracujete-li tedy napriklad pod uzivatelskym oznacenim novak, provedou se uvedene substituce nasledujicim zpusobem: ~ [---L /usr/home/novak ~novy [---L /usr/home/novy Alternativni povely (aliasy) C shell a Korn shell umoznuji definovat alternativni povely, kte- re jsou prekladany do skutecnych povelu, kdykoli se objevi v povelove radce. Tyto tzv. aliasy mohou byt uzity ke zmene implicitnich nastave- ni v povelech nebo ke zkraceni dlouhych povelovych radek pouzitim vhodne zkratky. Muzete si tedy napriklad zajistit, aby alias rm alter- noval povel rm -i (zmena implicitniho nastaveni; zde vyzadane potvrze- ni pred zrusenim kazdeho souboru) a alias ux alternoval povel chmod u+x (zkraceni povelove radky). C shell obsahuje take prostredek nazyvany historie (history), ktery substituuje predchozi povelove radky nebo jejich casti do aktu- alni povelove radky (viz odst.6.2). Take Korn shell se svym mechanismem historie (history mechanism) umoznuje, i kdyz jinymi prostredky nez C shell, vracet se k predchozim povelovym radkam, libovolne je menit a znovu provadet (viz kap. 13). 2.2.1 Substituce promennych Substituce promennych umoznuje uzivateli: . Zavest zkracene oznaceni pro casto uzivane znakove retezce. Ne- ktere z techto promennych ve funkci zkratky jako HOME nebo TMPDIR jsou inicializovany systemem, kdyz se do neho prihlasite (tedy po uvedeni login a Password). . Oznamit dulezite hodnoty procesum (pres promenne prostredi), napr. s jakym terminalem pracujete (promenna TERM). Hodnoty techto promennych muzete sami nastavit, aby povel dostal infor- mace, ktere potrebuje ke svemu uspesnemu provedeni. . Zjistit zmeny ve stavu relace nebo aktualniho shellu (pomoci specialnich promennych). Nektere z nich maji i specialne vytvo- rena jmena, napr. ? (pro Bourne a Korn shell, odpovidajici pro- menna pro C shell je status); odkaz na tuto promennou ($?) se preklada jako vystupni stav (exit status) posledniho dokoncene- ho povelu na popredi. Abyste zjistili nastaveni vsech svych promennych, pouzijte v Bourne a Korn shellu povelu set, v C shellu pak navic na vypis promen- nych prostredi povelu env. V Bourne a Korn shellu muzete povel env po- uzit take, dostanete vsak jen podmnozinu vypisu od set. Uvedme priklad v C shellu: cray140% set .... cwd /usr/home/novak/PRAC/A2S history 100 home /home/novak path (/bin /usr/bin /usr/lbin /usr/ucb /home/novak/bin .) .... prompt cray\!% .... shell /bin/csh status 0 term xterm user novak cray141% env .... DISPLAY=xterm14:0.0 TERM=xterm TMPDIR=/tmp/jtmp.0072929 HOME=/home/novak .... PATH=/bin:/usr/bin:/usr/lbin:/usr/ucb:/home/novak/bin:. LOGNAME=novak .... SHELL=bin/csh WORK=/tmp/novak LINES=24 .... Seznam bezne pouzivanych promennych s popisem jejich vyznamu na- leznete v [3] a v manualu [4]. O teto problematice take viz odst.2.5. Kdykoli shell objevi konstrukci $promenna, prelozi tento retezec vzdy do hodnoty promenne promenna. Napriklad kdyz chcete, aby se vasim pracovnim adresarem stal vas docasny adresar (pod adresarem /tmp), na- pisete jako povelovou radku cray142% cd $TMPDIR cray143% pwd /tmp/jtmp.0072929 cray144% (posledni povel jen vypise jmeno nove nastaveneho pracovniho adresa- re). Abyste nastavili hodnotu promenne promenna, pouzijte v Bourne a Korn shellu syntaxi promenna=hodnota v C shellu pak set promenna=hodnota nebo set promenna = hodnota Abyste z promenne promenna ucinili promennou prostredi, pridate v Bourne a Korn shellu povel export promenna v C shellu pak pouzijete misto povelu set povel setenv promenna hodnota V kazdem shellu existuji nektere specialni promenne, jako napr. ve vsech trech shellech promenna $, obsahujici PID aktualniho shellu. V Bourne a Korn shellu je to dale napr. promenna ?, ktera obsahuje vy- stupni stav posledniho povelu na popredi (nulovy v pripade uspesneho provedeni povelu, nenulovy v pripade provedeni neuspesneho); v C shel- lu je odpovidajici promenna status. Tyto promenne nastavuje shell a uzivatel nema moznost je menit; neobjevi se take na seznamu obsazenych promennych na vystupu povelu set. Dochazi vsak k jejich substituci na povelove radce jako u kterekoli jine promenne. K vyse recenemu jeden ilustracni priklad v Korn shellu: $ echo $TERM xterm $ echo Shell PID: $$ Vystupni stav: $? Shell PID: 65476 Vystupni stav: 0 $ TERM=notype $ export TERM $ echo $TERM notype $ vi $HOME/.profile notype: Unknown terminal type I don t know what kind of terminal you are on - all I have is notype . [Using open mode] "/home/novak/.profile" 6 lines, 118 characters 1 PATH=$PATH:$HOME/bin:. :q! $ echo $? 1 $ Promenne, ktere uz dale nebudete potrebovat, lze ve vsech trech shellech zrusit povelem unset, napr. v C shellu cray130% set A=1 cray131% set B=2 cray132% echo $A $B 1 2 cray133% unset A B 2.2.2 Povelova substituce Povelova substituce je uzitecna pro nasledujici situace: . Zahrnuti vystupu nejakeho povelu do povelu echo, napr. cray160% echo Je prave: `date | cut -c12-19` Je prave: 17:58:20 cray161% . Nastaveni hodnoty promenne z vystupu povelu, napr. cray151% set A=`wc -l program1.f` cray152% echo $A 224 program1.f cray153% . Interpretace vystupu povelu jako povel. . Uziti vystupu povelu v logickem vyrazu (pri uziti shellu jako programovaciho jazyka). Ve vsech shellech je syntaxe povelove substituce nasledujici: `druhotna_povelova_radka` Korn shell umoznuje take tuto - ne vsak zcela alternativni - syntaxi: $(druhotna_povelova_radka) Kdyz shell narazi na vyraz povelove substituce uvnitr povelove radky, provede druhotnou povelovu radku, ziska z ni vystup a zapise jej do hlavni povelove radky misto vyrazu povelove substituce. 2.2.3 Generovani jmen souboru (metaznaky) O principu generovani jmen souboru jsme se kratce zminili v odst. 2.2. Znaky *, ?, [ a ] ve vzoru pro jmena souboru jsou tzv. metaznaky (metacharacters), ktere maji nasledujici vyznam: Metaznak Vyznam * jakykoli pocet vyskytu jakehokoli znaku ? jakykoli jeden znak [acy] jakykoli znak z mnoziny znaku uvnitr za- vorek, zde tedy a, c nebo y [x-z] jakykoli ze znaku v rozsahu od-do, zde tedy "od x do z" Prohledavani podle vzoru nezahrnuje tecku (.) na zacatku jmena soubo- ru; tento znak musi byt zadan explicitne. Vygenerovany seznam jmen souboru, ktera vyhovuji pouzitemu vzoru, je abecedne serazen podle tabulky ASCII kodu. 2.2.4 Vlnovkova (tilda) substituce a alternativni povely (aliasy) O vlnovkove substituci bylo vse podstatne receno v odst.2.2. Take o vyznamu alternativnich povelu (aliasu) jsme se jiz zmini- li. Nyni uvedme technickou stranku veci. V Korn shellu je syntaxe pro definici aliasu tato: alias alternativni_povel= hodnota napr. tedy: alias rm= rm -i Po teto definici alias rm alternuje povel rm -i (pred zrusenim souboru dostanete vzdy vyzvu k potvrzeni), tedy $ rm program1.f program1.f: ? y $ (druha mozna odpoved je n). V C shellu je pro definici aliasu ekvivalentni tento zapis: alias alternativni_povel hodnota napr. tedy: cray105% alias dnes date | cut -c 1-11,25- cray106% dnes Tue Dec 13 1994 cray107% Jak je z prikladu zrejme, po definici aliasu oba shelly prelozi alternativni_povel do hodnoty, kdykoli se alias v povelove radce obje- vi. V obou shellech vypise povel alias (bez parametru) seznam vsech aktualnich aliasu. 2.3 Presmerovani standardnich souboru Jednim ze silnych prostredku kazdeho unixoveho shellu je jeho schopnost presmerovat standardni vstup (stdin) z jineho souboru nebo standardni vystup (stdout) a standardni chybovy soubor (stderr) do ji- neho souboru, nez jsou soubory implicitni (klavesnice, resp. obrazov- ka). V nasledujicim prehledu uvedeme konstrukce, jimiz toho lze dosah- nout: u-------------------i------------i-----------------------------------o p Konstrukce p Shelly p Vyznam p u-------------------i------------i-----------------------------------o p < vstupni_soubor p sh ksh csh p stdin je cten ze vstupniho_soubo- p p p p ru p p > vystupni_soubor p sh ksh csh p stdout je zapisovan do vystupni- p p p p ho_souboru. Pokud vystupni_soubor p p p p jiz existuje, bude jeho obsah p p p p znicen. V Korn a C shellu muzete p p p p soubory proti teto destrukci p p p p ochranit. V Korn shellu zadejte p p p p povel p p p p p p p p set -o noclobber p p p p p p p p v C shellu povel p p p p p p p p set noclobber p p p p p p p p Bourne shell obdobnou ochranu ne- p p p p poskytuje. p p p p p p 2> chybovy_soubor p sh ksh p stderr je zapsan do chybove- p p p p ho_souboru. O prepsani chybove- p p p p ho_souboru a jeho mozne ochrane p p p p plati, co bylo receno vyse o p p p p vystupnim_souboru. p p p p p p >& spolecny_sou- p csh p stdout a stderr jsou oba zapsany p p bor p p do spolecneho_souboru. O prepsani p p p p spolecneho_souboru a jeho mozne p p p p ochrane plati, co bylo receno vy- p p p p se o vystupnim_souboru. p p >> prodluzova- p sh ksh csh p stdout je pridan na konec pro- p p ny_soubor p p dluzovaneho_souboru p p << konec_souboru p sh ksh csh p stdin je cten z radek, ktere na- p p .... p p sleduji povelovou radku, dokud p p telo_souboru p p shell nenarazi na slovo konec_ p p .... p p souboru, ktere je definovano na p p konec_souboru p p povelove radce za symbolem <<. p p p p Slovem konec_souboru muze byt p p p p treba jen jediny znak, napr. vy- p p p p kricnik (!). p m--------------------------------------------------------------------. Dalsim zpusobem manipulace se standardnim vstupem a vystupem je tzv. roura (pipe). Vyuzijete ji tehdy, jestlize vystup jednoho povelu ma byt vstupem pro povel jiny. Napriklad povelovou radkou $ ls | pg dosahnete toho, ze vystup z povelu ls se stane vstupem pro povel pg a tedy obsah pracovniho adresare se bude vypisovat na obrazovku po strankach. 2.4 Vyhledani povelu a jeho provedeni 2.4.1 Vyhledani povelu Po zpracovani povelove radky musi shell zadany povel nekde na- lezt. Povel muze byt bud vestaveny povel (built-in command), shellov- ska funkce (shell function) nebo proveditelny povel (executable com- mand). Vestavene povely jsou castmi samotneho shellu. Jsou mnohdy speci- ficke u kazdeho shellu a nektere nemaji sve man stranky (viz prirucka [2], odst.4.1). Uvedme nektere priklady vestavenych povelu: Vsechny tri shelly: exit cd umask set Pouze Korn a C shell: alias Pouze Bourne a Korn shell: export Podrobnejsi informace o vestavenych povelech naleznete v manualu [4]. Shellovske funkce, ktere je mozne vytvorit pouze v Bourne a Korn shellu, jsou jako uzivatelem definovane vestavene povely. K definovani shellovske funkce slouzi nasledujici syntaxe: funkce () { povely } Prikladem budiz definice funkce rm s vyzadanym potvrzenim pred zrusenim kazdeho souboru. V interaktivnim rezimu po zapsani prvni rad- ky definice funkce nabidne shell sekundarni prompt (zde >), oznacujici neuplnost povelu; konstrukce $* zde zastupuje "vsechny parametry shel- lovske funkce": $ rm () { > /bin/rm -i $* > } $ rm p* program1.f ? n $ Pote, co shell zkontroluje, zda se nejedna o vestaveny povel, zkontro- luje, zda povel neni shellovska funkce; neni-li, shell hleda dale mezi proveditelnymi povely. Proveditelne povely jsou spousteny z proveditelnych souboru (pri- stupove pravo x) jako procesy. Shell nalezne tyto soubory v hasovaci tabulce (hash table) nebo pomoci promenne PATH. PATH je promenna prostredi, v niz je ulozen seznam vsech adresa- ru, ve kterych se maji proveditelne soubory hledat. Hasovaci tabulka obsahuje "zkratky" pro povely, ktere jiz byly pres PATH nalezeny. V teto souvislosti je pro praci se C shellem dulezity jeho vesta- veny povel rehash, ktery aktualizuje hasovaci tabulku s obsahy adresa- ru z promenne PATH. To je potrebne tehdy, kdyz pridate novy provedi- telny povel do nektereho z adresaru, uvedenych v promenne PATH, jehoz jste vlastnikem (nejcasteji do adresare $HOME/bin). Hasovaci tabulka se take aktualizuje pri kazde zmene hodnoty promenne PATH. Shell prohledava adresare v poradi, v jakem jsou uvedeny v pro- menne PATH. Necht napriklad cray162% echo $PATH /bin:/usr/bin:/usr/lbin:/usr/ucb:/home/novak/bin:. Potom je povel hledan nejprve v adresari /bin, pote v adresari /usr/bin a tak dale, az nakonec v pracovnim adresari (.). Kazdy shell ma vestaveny povel, ktery oznami typ povelu (alias, vestaveny, funkce nebo proveditelny); v pripade proveditelneho povelu uda i absolutni cestu k odpovidajicimu souboru. V Bourne a Korn shellu je to povel type jmeno_povelu v C shellu povel which jmeno_povelu 2.4.2 Provedeni povelu Kdyz shell precetl a zpracoval povelovou radku a povel byl nale- zen jako proveditelny soubor, povel sam je vykonan takto: 1. Shell vytvori synovsky proces pres systemove volani fork. Nyni: . Synovsky proces je nova polozka v systemove tabulce proce- su a ziska nove cislo procesu (v nasledujicim priklade 65009)... . Synovsky proces je kopie jeste beziciho stareho csh pro- gramu. . Syn zdedi kopie prostredi otcovskeho procesu, coz je mno- zina charakteristik zahrnujici (mezi jinymi charakteristi- kami) tez hodnoty pro vlastnika, skupinu, promenne pro- stredi a pracovni adresar. . Otcovsky proces (puvodni csh) ceka, az se syn ukonci (po- kud vsak nebyl povel spusten na pozadi). 2. Synovsky proces provede povelem specifikovana nastaveni, ktera byla zjistena, kdyz otcovsky shell interpretoval povelovou radku. Sy- novsky shell napr. otevre nejake soubory pro implementaci presmerovani vstupu nebo vystupu. 3. Synovsky proces vykona exec, cimz dojde k prekryti stareho programu (csh) programem novym (v prikladu ps). 4. Kdyz synovsky proces (ps) skonci, posle signal "smrt syna" otci (csh), ktery pak obnovi svou normalni cinnost. O procesech se lze vice docist v prirucce [2], kap. 2. Priklad: cray170% ps -f UID PID PPID TTY TIME COMMAND novak 65009 64921 p016 0:00 ps novak 64921 64915 p016 0:00 csh cray171% PID=64921 "otec" u-----------------------------------------------------o p Prostredi p u----------i-----------------------------i------------o p csh p zde csh ceka p p [-----------------------------------------------------] p p p p u-----------------------------o p Prostredi (zdedene) p u-----i-----------------------o p csh p ps p [-----------------------------] exec 2.5 Rizeni uzivatelova prostredi Shell nastavi a spravuje promenne prostredi, coz jsou promenne, ktere sdeluji dalsim procesum uzitecne informace. Napr. promenna TERM rika editoru vi, jaky typ terminalu uzivatel ma. Ve vsech shellech pouhe prirazeni hodnot promennym vytvari pouze lokalni promenne (local variables). Tyto lokalni promenne jsou znamy shellu, ale ne jiz jake- mukoli jinemu procesu. Uzivatel proto musi udelat vice nez pouhe pri- razeni hodnoty promenne, aby se z promenne stala promenna prostredi (a stala se tak znamou i dalsim vzniknuvsim procesum). Abyste zjistili, ktere z promennych jsou promenne prostredi, pouzijte povel env. Muzete tedy obdrzet napr. cray175% env .... DISPLAY=xterm14:0.0 TERM=xterm TMPDIR=/tmp/jtmp.014149a HOME=/home/novak .... cray176% V Bourne a Korn shellu zmenite lokalni promennou promenna na pro- mennou prostredi povelem export promenna Je tedy zrejme, ze v techto dvou shellech jsou promenne prostredi podmnozinou lokalnich promennych (a tedy i vystup povelu env bude cas- ti vystupu povelu set). V C shellu je prirazeni hodnoty lokalni promenne zcela oddeleno od prirazeni hodnoty promenne prostredi. Lokalni promenna vyzaduje po- vel set lokalni_promenna=hodnota zatimco promenna prostredi vyzaduje povel setenv promenna_prostredi hodnota Z tohoto duvodu jsou promenne prostredi zcela oddeleny od lokal- nich promennych (obe mnoziny jsou disjunktni a tedy vystupy povelu env a set neobsahuji zadnou spolecnou promennou; povel setenv bez paramet- ru poskytne vystup shodny s vystupem povelu env). C shell ma vsak jed- nu tridu vyjimek z tohoto pravidla. Existuji urcite lokalni promenne (v malych pismenech), z nichz kazda je automaticky prevedena take do sveho ekvivalentu promenne prostredi (ve velkych pismenech); jsou to lokalni promenna promenna prostredi home HOME path PATH shell SHELL term TERM Pro vsechny tyto lokalni promenne neni zapotrebi uzit povelu setenv, nebot povel set lokalni_promenna=hodnota nastavi jak lokalni promennou, tak promennou prostredi. Priklad: cray180% env | grep TERM TERM=xterm cray181% unset term cray182% unset TERM cray183% echo $TERM TERM: Undefined variable. cray184% set term=xterm cray185% echo $TERM xterm cray186% Prostredkum programovaciho rozhrani se venuji kapitoly 6 az 13. 2.6 Ulozeni a zpristupneni predchozich povelu Korn a C shell umoznuji uzivateli ulozit a zpristupnit drive pro- vedene povely. C shell uziva substitucni metodu, Korn shell umoznuje primy pristup k predchozim povelum. C shell poskytuje prostredky pro ocislovani, vyhledavani a meneni predchozich povelu. Muzete tedy rych- le zadat nektery z predchozich povelu k opetovnemu provedeni nebo se odkazat na nektery parametr nektereho z predchozich povelu pri vytva- reni povelu noveho. V tomto odstavci se zminime pouze o C shellu, pro- toze je na Crayi obvyklym login shellem. C shell si zapamatovava jednotlive povely jako ocislovane udalos- ti (events) ve specialni vyrovnavaci pameti (history list). Pro snadne urceni cisla udalosti (povelu), ke ktere se chceme vratit, je vhodne vlozit toto cislo do vlastniho promptu. Provede se to povelem typu set prompt= cray\!% Dulezitou soucasti retezce v tomto povelu je dvojice znaku \!, ktera se pri kazdem nabidnuti promptu shellem meni na cislo udalosti. Cislo udalosti se meni od jedne po jedne. Ostatni znaky (zde slovo cray, znak % a mezera) se opakuji beze zmeny pri kazde nabidce promp- tu, napr. cray101% ls a.out program1.f cray102% Pocet predchozich udalosti, ktere si ma C shell zapamatovat (a k nimz se tedy muzete pozdeji vracet), je stanoven hodnotou promenne history. Aby si C shell pamatoval napr. poslednich 30 udalosti, nasta- vi se history na tuto hodnotu povelem set history=30 Pokud neni promenne history prirazena nejaka hodnota, pamatuje si C shell pouze posledni udalost. Nastaveni promennych prompt a history byste meli mit ve svem sou- boru .login. Nasledujici prehled ukazuje prostredky pro odkazy na predesle udalosti (a tim i jim odpovidajici povely) nebo jejich casti. V tomto smyslu zde mluvime o provedeni udalosti nebo parametru udalosti misto o provedeni povelu nebo parametru povelu apod. Povel Vyznam !n^ vybere 1. parametr (2. slovo zleva) z udalos- ti n !n$ vybere posledni parametr z udalosti n !n* vybere vsechny parametry z udalosti n !n:m vybere m-ty parametr z udalosti n !n:0 vybere 1. slovo (povel) z udalosti n !! provede znovu bezprostredne predchazejici udalost !-n provede znovu udalost "n-tou dozadu" !retezec provede znovu nejblizsi udalost zacinajici retezcem !n provede znovu udalost n ^retezec1^retezec2 provede bezprostredne predchozi udalost, v niz je retezec1 nahrazen retezcem2 Priklad: cray101% ls /home/novak/STRUKTURA1 program1.f program2.f cray102% cd !101$ cd /home/novak/STRUKTURA1 cray103% vi program1.f .... editace zdrojoveho souboru, pri niz jsme neudelali vse, co jsme chteli .... cray104% !! vi program1.f .... dokonceni editace .... cray105% ^1^2 vi program2.f .... editace dalsiho zdrojoveho souboru .... cray106% K zobrazeni vsech udalosti, ktere si C shell prave pamatuje, slouzi povel history 2.7 Rizeni procesu na pozadi Vsechny povely, o kterych jsme dosud mluvili, byly spousteny na popredi (foreground) (tedy presneji: jim odpovidajici procesy byly spousteny na popredi), coz znamena, ze povel byl po zadani proveden a uzivatel ocekaval vystup promptu, kterym mu bylo sdeleno, ze provedeni bylo ukonceno. Bez toho, abychom cekali na ukonceni povelu, a bylo nam umozneno zadat povel dalsi, je mozne spustit povel na pozadi (back- ground). Spoustet povely (procesy) na pozadi muzete v kteremkoli shellu. Mezi duvody, proc k tomuto druhu spousteni pristoupit, patri prede- vsim: . proces ma bezet nepretrzite (do teto kategorie spada vetsina systemovych demonu); . program ma bezet dosti dlouho, ale ne zase tak dlouho, abyste jej zadali pres NQS jako davkovou ulohu. Spusteni povelu na pozadi se dosahne uvedenim znaku ampersand (&) jako posledniho na povelove radce. Dale je samozrejme mozne zkontrolo- vat povelem ps stav vsech procesu v ramci seance (tedy i procesu bezi- cich na pozadi) a kteremukoli zadat signal povelem kill pid; prijima- jici proces pak ve vetsine pripadu ukonci svoji cinnost. Krome vyse receneho poskytuji Korn a C shell prostredky pro rize- ni uloh na pozadi, ktere: . priradi cislo ulohy kazdemu procesu bezicimu na pozadi. (V na- sledujicim prikladu udalost 203, dlouhy_program &, bezi jako uloha cislo 1, udalost 204, obcas_ctu &, bezi jako uloha cislo 2.) . ukazuji stav uloh pres povel jobs, jak znazornuje udalost 205. V prvnim sloupci vystupu je cislo ulohy, ve druhem indikace po- radi (pro posledni ulohu je zde znak +, pro predposledni znak -, drivejsi ulohy maji v tomto sloupci mezeru), ve tretim sloupci je stav ulohy (obvykle "Running" nebo "Stopped") a v poslednim povelova radka, ktera ulohu spustila. . umoznuji zastavit ulohu bezici na pozadi povelem stop %cislo_ulohy jak je ukazano udalosti 208, ktera zastavuje program obcas_ctu. . umoznuji zastavit ulohy na popredi (kombinaci klaves , viz pred udalosti 207). . automaticky zastavuji ulohu na pozadi, kdyz chce tato uloha cist ze standardniho vstupu. Pred udalosti 206 program obcas_ctu uzivatele pozada o vstup a zastavuje se, cekaje na tento vstup. . umoznuji vam pokracovat se zastavenou ulohou na popredi (povel fg) nebo na pozadi (povel bg). Udalost 206 posila zastavenou ulohu na popredi, coz ji umozni precist si vstup ze stdin. Uda- lost 207 ji posila zpet na pozadi. . umoznuji vam zrusit ulohu za pomoci jejiho cisla (zde zadanim signalu 9), jak ukazuje udalost 210. Priklad: cray203% dlouhy_program & [1] 75110 cray204% obcas_ctu & [2] 75205 cray205% jobs [2] + Running obcas_ctu & [1] - Running dlouhy_program & cray206% Zadejte data pro obcas_ctu: [2] + Stopped (tty input) obcas_ctu & cray206% fg %2 obcas_ctu .... data pro obcas_ctu .... [2] + Stopped obcas_ctu & cray207% bg %2 [2] obcas_ctu & cray208% stop %2 [2] + Stopped(signal) obcas_ctu & cray209% jobs [2] + Stopped(signal) obcas_ctu & [1] - Running dlouhy_program & cray210% kill -9 %2 cray211% [2] + Killed obcas_ctu & cray211% 3. Poradi akci pri provadeni povelu V kap. 2 jsme se seznamili s funkcemi shellu; nyni je shrnme v poradi, ve kterem se tyto funkce uplatnuji: 1. Precteni povelove radky - shell cte povelovou radku tak, jak byla zadana z klavesnice nebo ze scenare. 2. Interpretace povelove radky - k ni dochazi, jestlize radka ob- sahuje substituce a presmerovani standardnich souboru. 3. Vyhledani povelu - shell hleda povel v tomto poradi: - seznam vestavenych povelu; - seznam shellovskych funkci (pouze sh a ksh); - hasovaci tabulka (zkratky pro povely jiz nalezene pres promennou PATH); - adresare specifikovane promennou PATH. Akce je ukoncena, jakmile shell povel nalezne. 4. Provedeni povelu - jestlize je povel nalezen v hasovaci tabul- ce nebo pres promennou PATH, shell spusti povel jako synovsky proces. 5. Cekani na dokonceni - shell ceka na dokonceni povelu (pokud povel nebezi na pozadi) a teprve pak pokracuje. Nyni muze zacit tato posloupnost znovu od pocatku pro dalsi pove- lovou radku. Zastavme se nyni kratce u druhe akce, interpretace povelove rad- ky, ktera predstavuje znacnou cast toho, co shell dela. Organizace te- to cinnosti se v jednotlivych shellech ponekud lisi. Nasledujici pre- hled ukazuje poradi interpretace pro jednotlive shelly: u----------------------i----------------------i----------------------o p sh p ksh p csh p u----------------------i----------------------i----------------------o p p p Substituce "historie"p p p Aliasy p Aliasy p p p Vlnovkova substituce p p p Povelova substituce p Povelova substituce p Povelova substituce p p Substituce promen- p Substituce promen- p Substituce promen- p p nych p nych p nych p p p Generovani jmen p Generovani jmen sou- p p p souboru p boru (vcetne vlnov- p p p p kove substituce) p p Presmerovani stan- p Presmerovani stan- p Presmerovani stan- p p dardnich souboru p dardnich souboru p dardnich souboru p p Generovani jmen p p p p souboru p p p m--------------------------------------------------------------------. Napriklad tedy v Bourne shellu nemuzete pouzit generovani jmen souboru v presmerovani standardnich souboru, protoze toto presmerovani se pro- vede pred generovanim jmen souboru. Dalsi dva shelly toto omezeni ne- maji, protoze u nich je poradi techto dvou cinnosti opacne. 4. Modifikace povelove radky V teto kapitole pohovorime o tom, jak muze byt shellovska inter- pretace povelove radky modifikovana. 4.1 Modifikatory povelove radky Jiz vite, ze existuje nekolik moznosti, jak shellu rici neco o zpusobu zpracovani povelu: ampersand (&) pridany na konec povelu shel- lu sdeli, ze povel ma byt spusten na pozadi, standardni soubory mohou byt presmerovany, dva nebo vice povelu spolu muze komunikovat pres rouru. Zminme zde jeste nektere dalsi moznosti, ktere jsou spolecne pro vsechny tri shelly. Oddeleni povelu Dva nebo vice povelu muze byt zapsano na jedne povelove radce s tim, ze maji byt vykonany jeden po druhem zleva doprava. Povely jsou oddeleny strednikem (;). Shelly maji dva specialni oddelovace povelu, ktere vam umoznuji provest povel v zavislosti na tom, zda predchozi povel probehl uspesne ci neuspesne. Oddelovac && znamena, ze se druhy povel spusti jen teh- dy, kdyz prvni probehl uspesne. Oddelovac || znamena, ze se druhy po- vel spusti jen tehdy, kdyz prvni probehl neuspesne. Priklad: cray230% pwd ; ls /usr/home/novak/STRUKTURA1 data1 data2 program1.f cray231% cf77 program1.f && a.out vystup /usr/home/novak cray102% more vystup Wed Dec 28 20:31:10 MEZ 1994 cray103% (pwd ; date) >vystup cray104% more vystup /usr/home/novak Wed Dec 28 20:32:13 MEZ 1994 cray105% Poznamky Poznamky jsou dulezite k tomu, abychom oznacili, proc je ktery povel provaden, a nebo co ktery povel dela. Jsou dulezite zvlaste v shellovskych scenarich, kde jich muzete vyuzit i pri ladeni (radky s ladicimi povely postupne menite na poznamkove radky, jakmile jste v predchozi casti scenare dosahli zadaneho efektu). Za poznamku je pova- zovano vse od znaku mrizka (#) do konce radky. Priklad: $ # Tato radka je ignorovana $ ls # Tato cast radky je ignorovana a.out data1 data2 program1.f $ 4.2 Uvozovkovy aparat a povel eval V terminologii UNIXu termin "ocitovat" (slangove "ouvozovkovat") jeden nebo vice znaku znamena odstranit nejaky jeho specialni vyznam, ktery pro shell ma. S radou takovych znaku nebo retezcu jsme se jiz setkali (napr. $, *, |, && aj.). V mnoha pripadech potrebujete tyto znaky nebo retezce jako literaly, tedy potrebujete nikoli jejich zvlastni vyznam pro shell, ale "je samotne". K tomu vam slouzi prave uvozovkovy aparat. Shelly podporuji tri jeho urovne: Zpetne lomitko (\x) Predrazenim znaku zpetne lomitko (\) muzete odstranit specialni vyznam libovolneho znaku. Toto je nejsilnejsi uroven uvozovkoveho apa- ratu, protoze muze odstranit specialni vyznam jakehokoli, tedy i ne- tistitelneho znaku (napr. ). Jestlize tedy napisete znak \ bez- prostredne pred , pokracuje povel na dalsi radce. Jestlize na- pisete \ pred prvni pismeno aliasu, odstranite aliasovy vyznam tohoto povelu. Priklad: Prvni povelova radka obsahuje specialni znaky $, *, ~, ;, ` a #, druha povelova radka ma u vsech techto znaku jejich special- ni vyznam odstranen: cray101% echo $TERM d* ~ ; echo `pwd` #xx xterm data1 data2 /home/novak /usr/home/novak/STRUKTURA1 cray102% echo \$TERM d\* \~ \; echo \`pwd\` \#xx $TERM d* ~ ; echo `pwd` #xx cray103% Silna uroven ( xxx ) Druha uroven uvozovkoveho aparatu, oznacovana jako silna (strong), pouziva dvojice apostrofu ('); uvnitr apostrofu ztraci svuj specialni vyznam jakykoli tistitelny specialni znak krome apostrofu. Retezce mezi apostrofy jsou dulezite pro provedeni takovych pove- lu jako grep, protoze znaky regularnich vyrazu (ktere maji byt inter- pretovany napr. povelem grep) jsou casto shodne se znaky ve vzorech pro generovani jmen souboru (ktere maji byt interpretovany shellem). Regularni vyraz COM.* (jakykoli znakovy retezec zacinajici trojici znaku COM) neni totez co vzor pro generovani jmen souboru COM.* (jake- koli jmeno souboru zacinajici ctverici znaku COM.). O regularnich vy- razech (regular expressions), na nez jsme v tomto kontextu narazili, se lze podrobne poucit v manualu [7]. Priklad: cray110% ls .... COM.f .... cray111% grep COM.* COM.* COMMON /x/ A, B, C cray112% Slaba uroven ("xxx") Ve treti urovni uvozovkoveho aparatu, oznacovane jako slaba (week), se pouziva dvojice znaku uvozovky ("); retezec znaku v uvozov- kach je povazovan za "slabsi" nez retezec znaku v apostrofech. Je tomu tak proto, ze substituce promennych ($promenna) a povelova substituce (`povel`) se jeste uvnitr uvozovek provedou. Priklad: cray120% echo "$TERM d* ~ ; echo `pwd` #xx" xterm d* ~ ; echo /usr/home/novak/STRUKTURA1 #xx cray121% Poslednim z prostredku shellu pro modifikaci povelove radky, o kterem se zde strucne zminime, je povel eval. Pomoci tohoto povelu, ktery je soucasti vsech tri shellu, muzete zajistit viceurovnovou in- terpretaci povelovych substituci nebo substituci promennych, cimz se muzete vyhnout napriklad omezenim, ktera vytvari pevne stanovene pora- di akci pri provadeni povelu, o nemz jsme hovorili v kap. 3. Podrobne- ji se muzete o povelu eval docist napr. v manualu [5], zde jen na pri- kladu ukazme "dvojite" zpracovani povelove radky pomoci tohoto povelu: cray130% set jedna=`ls` cray131% set dve= $jedna cray132% echo $dve $jedna cray133% eval echo $dve a.out data1 data2 program1.f cray134% 5. Pocitacova relace V teto kapitole probereme jednotlive faze pocitacove relace pro uzivatele pracujiciho v interaktivnim rezimu nebo pri zadavani davkove ulohy. Kontrola platnosti uzivatele Pri interaktivnim prihlaseni uzivatele do systemu je nutne zadat platne uzivatelske oznaceni (na vyzvu systemu login:) a jemu odpovida- jici heslo (na vyzvu systemu Password:); heslo se na obrazovce neopi- suje. Davkove ulohy zadane pres NQS heslo nekontroluji. Systemova inicializace Systemovy administrator nastavi implicitni inicializacni soubory. Soubor /etc/profile inicializuje uzivatelovo prostredi v Bourne a Korn shellu. Soubor /etc/cshrc inicializuje uzivatelovo prostredi v C shellu. Inicializace pri prihlaseni uzivatele do systemu Kterykoli uzivatel muze rozsirit sve uzivatelske prostredi umi- stenim povelu do inicializacniho souboru (napr. nastaveni hodnot pro- mennych, aliasy aj.). Pro uzivatele Bourne a Korn shellu je timto ini- cializacnim souborem .profile v domovskem adresari, pro uzivatele C shellu je jim .login v domovskem adresari. Typicky inicializacni sou- bor muze obsahovat povely, ktere zajisti napr. nastaveni pristupovych prav souboru pri jeho vytvoreni, nastaveni typu terminalu, modifikaci seznamu adresaru, kde se maji hledat proveditelne povely, definovani dalsich uzivatelovych promennych prostredi apod. Shellovska inicializace Casto se shellovske procesy jine nez login shell provadeji jako jeho synovske procesy. Tyto subshelly (subshells) jsou vytvareny napr. kdykoli uzivatel: - provede shellovsky scenar jako povel; - sdruzi povely do skupiny pomoci zavorek ( a ); - provede povel sh, ksh nebo csh; - zpristupni UNICOS pres vzdaleny shellovsky povel (remote shell command) po siti; - v grafickem prostredi otevre okno se shellem. Muze byt zadouci pripravit si soubor pro univerzalni povely, kte re bude potrebovat kazdy shell stejne tak jako soubor se specializova- nejsimi povely pro login shell. Napr. v Korn shellu nemuzete exporto- vat aliasy a funkce tak zcela jako promenne. Univerzalni shellovska inicializace poskytne subshellum moznost mit take aliasy a funkce. V Korn shellu je mozne jmeno tohoto shellovskeho inicializacniho souboru menit; timto jmenem je hodnota promenne prostredi ENV. To vam umoznuje vytvorit ruzne shellovske inicializacni soubory pro ruzne ucely, napr. zvlast pro davkove a zvlast pro interaktivni ulohy. V C shellu je shellovskym inicializacnim souborem .cshrc ve vasem domovskem adresa- ri. Dulezitou odlisnosti C shellu je to, ze se soubor .cshrc provadi pred souborem .login, tedy shellovska inicializace probehne pred ini- cializaci pri prihlaseni uzivatele do systemu. V Korn shellu je tomu naopak. Uzivatelovy povely Po ukonceni inicializace muze uzivatel zadavat povely. Odhlaseni od systemu Ukonceni pocitacove relace je mozne ruznymi zpusoby (v C shellu napr. povelem quit), ve vsech shellech vsak funguje povel exit. V C shellu si muzete v souboru .logout ve svem domovskem adresari pripra- vit povely, ktere se maji provest pri odhlaseni od systemu. (Zde lze stezi neco univerzalne radit; spektrum je od rozsahle testovaci cinnosti nejruznejsich systemovych aktivit az po mile rozlouceni se systemem povelem echo Goodbye!). V Bourne a Korn shellu muzete podob- neho vysledku dosahnout povelem trap. 6. Shellovske programy Dulezitou funkci kazdeho shellu, kterou se budeme zabyvat v teto kapitole, je poskytnuti programoveho prostredi uzivateli; jinymi slovy shell muzete pouzivat jako specificky programovaci jazyk. Shell takovy program, nazyvany shellovsky program (shell program), interpretuje. Shellovsky program muze obsahovat povely UNICOSu nebo jakekoli jine konstrukce shellem rozpoznatelne, napr. nastaveni hodnot promennych, poznamky aj. 6.1 Typy shellovskych programu Shellovsky program se muze objevit jako interaktivni povel, funk- ce, alternativni povel nebo scenar. Interaktivni povely Posloupnost povelovych radek muze byt povazovana za program v tom smyslu, ze vsechny tri shelly umoznuji jakekoli shellovske programove prostredky na povelove radce. Priklad: Pomoci nasledujicich povelu se dozvite, zda je uzivatel novy prihlasen do systemu (slangove "zalogovan"). $ who | grep "novy" >/dev/null $ if [ $? = 0 ] > then echo novy je zalogovan > fi novy je zalogovan $ Funkce Shellovska funkce v Bourne a Korn shellu je jako makro uvnitr shellu, ve kterem je definovana. V nasledujicim prikladu je definovana funkce novyjez; timto identifikatorem se na funkci odvolavame. Za jme- nem funkce nasleduje v definici funkce dvojice kulatych zavorek () a telo funkce, coz je posloupnost povelu uvnitr slozenych zavorek { a }. Funkce jsou obvykle definovany v inicializacnich souborech, jakymi jsou vase soubory .profile nebo $ENV. Priklad: $ novyjez () { > who | grep "novy" >/dev/null > if [ $? = 0 ] > then echo novy je zalogovan > fi > } $ novyjez novy je zalogovan $ Alternativni povel (alias) Prostredek nazyvany alias je typem shellovske substituce, avsak alias v C shellu muze obsahovat uplny shellovsky program. Ackoli v nasledujicim prikladu je pro jednoduchost alias definovan z interak- tivni povelove radky, byvaji definice aliasu obvykle umisteny v ini- cializacnich souborech (.login nebo .cshrc). Priklad: cray101% alias novyjez \ 'who | grep "novy" >/dev/null' \ 'if ($status == 0) echo novy je zalogovan' cray102% novyjez novy je zalogovan cray103% Prostredek alias v Korn shellu neni tak pruzny jako jeho kolega v C shellu; rada prostredku shellovskych programu nemuze byt v definici aliasu v Korn shellu pouzita. Scenar Shellovsky scenar je soubor povelu a dalsich konstrukci, ktere maji byt shellem interpretovany. Mnohe prostredky se v jednotlivych shellech lisi, a proto je nutno rozlisovat mezi Bourne, Korn a C shel- lovskymi scenari. Korn shell je vsak kompatibilnim rozsirenim Bourne shellu, takze jakykoli scenar v Bourne shellu by mel fungovat i v Korn shellu. Priklad: Pri vytvoreni noveho scenare (zde souboru novyjez) ne- smime zapomenout na povoleni k jeho provadeni (povel chmod). $ cat >novyjez who | grep "novy" >/dev/null if [ $? = O ] then echo novy je zalogovan fi $ chmod u+x novyjez $ novyjez novy je zalogovan $ Nejbeznejsi shellovske programy jsou shellovske scenare; priklady shellovskeho programovani budou proto v dalsim textu psany prevazne jako shellovske scenare. Casto se dokonce terminy "shellovske progra- my" a "shellovske scenare" vzajemne zamenuji. 6.2 Proc psat shellovske programy ? Psani shellovskyvch programu prinasi uzivateli radu vyhod, mezi nez patri zvlaste moznosti zmen cinnosti povelu, vytvoreni prirozeneho proudu casto pouzivanych povelu pro vlastni pouziti nebo vytvoreni prototypu noveho programu. Zmena cinnosti povelu Uzivatel muze zmenit cinnost existujiciho povelu uzitim shel- lovskeho programu. Chcete napriklad, aby povel mel odlisne implicitni volby nebo aby provadel nektere dodatecne akce. V obou pripadech muze- te napsat shellovsky scenar, shellovskou funkci v Bourne nebo Korn shellu nebo alias v C shellu, ktere maji stejne jmeno jako povel, kte- ry menite. K tomu nekolik dulezitych poznamek: . V shellovskem programu (scenari, funkci nebo aliasu) byste meli specifikovat uplnou cestu k puvodnimu povelu, abyste se vyhnuli nekonecne sekvenci volani. . Abyste zmenili cinnost puvodniho povelu scenarem, shell musi nalezt vas scenar drive, nez najde povel puvodni. Proto by adresar, obsahujici vase scenare (obvykle $HOME/bin), mel byt prvni ve vasi promenne PATH. Nedavejte nikdy na prvni misto do promenne PATH vas pracovni adresar (.). . Pouziti uvedene techniky nezmeni cinnost vestavenych povelu. Prirozeny proud casto pouzivanych povelu Zapsanim casto uzivaneho povelu nebo skupiny povelu do shellov- skeho programu se muzete vyhnout dvema neprijemnostem: . nemusite si pamatovat obtizna jmena povelu nebo dlouhe seznamy voleb; . nemusite vzdy znovu psat dlouhou radu povelu pokazde, kdyz je chcete provest. Muzete si prejmenovat obtizne zapamatovatelne povely nebo vytvo- rit povely zcela nove. Stravite mene casu nahlizenim do manualu a opravou chyb, nebot v shellovskem povelu budete mit spravne (odladene) povelove radky. Muzete pak dokonce zapomenout na to, ze tyto nove po- vely jsou shellovske programy, protoze se budou chovat stejne jako ji- ne povely. Prototyp noveho programu Kdyz se setkate s tim, ze mate vytvorit rozsahly program, muzete si napsat shellovsky scenar jako prototyp tohoto programu neboli vy- tvorit si inicializacni pracovni model sveho ciloveho programu. Shel- lovsky scenar splnuje naroky na prototyp kladene, protoze scenare lze relativne snadno napsat a ladit; scenare mohou take vyuzivat jiz exis- tujici aplikace a utility. Jiste vam nikdo nenavrhuje psat rozsahle vedecke nebo technicke programy pouze uzitim povelu shellu nebo UNI- COSu, ale velmi dobre muzete vyuzit shellovsky program pro sdruzeni jiz existujicich aplikaci. Jakmile mate fungujici prototyp, byva jiz relativne snadne napsat vykonnejsi program ve fortranu nebo v jazyku C, ktery jej nahradi. 6.3 Prostredky shellovskych programu Jakykoli programovy prostredek, ktery pracuje v Bourne shellu, pracuje take v Korn shellu. Proto muzeme rozdelit odlisnosti v progra- movani do dvou kategorii: prostredky Bourne/Korn shellu a prostredky C shellu. Existuji i spolecne rysy, u nichz se nyni zastavime. Vsechny tri shelly poskytuji nasledujici programove prostredky: Promenne O shellovskych promennych jsme se zminili v odst.2.2.1. Pripomen- me, ze v Bourne/Korn shellu hodnotu lokalnich shellovskych promennych nastavujeme konstrukci promenna=hodnota v C shellu pak set promenna=hodnota Lokalni shellovske promenne se chovaji jako lokalni promenne v nejakem programovacim jazyku. Hodnotu promennych prostredi nastavujeme v Bour- ne/Korn shellu promenna=hodnota export prom v C shellu pak setenv promenna hodnota Promenne prostredi se chovaji jako globalni promenne, ale nejsou sku- tecne globalni, nebot zmeny v hodnote takove promenne nejsou prenaseny nazpet v hierarchii volani. Podprogramy V shellu jsou podprocesy analogicke podprogramum v programovacich jazycich, jakymi jsou napr. fortran nebo jazyk C. Proto kdykoli shel- lovsky program A spusti shellovsky program B jako synovsky proces, ri- kame, ze B je podprogramem programu A. Parametry Shellovske programy mohou pouzivat parametry, ktere se zapisuji na povelovou radku. Vstup/vystup V shellovskych programech jsou uzitecnymi prostredky presmerovani standardnich souboru a roura. Krome toho maji Bourne/Korn i C shell vlastni syntaxi pro cteni vstupu do promennych: Bourne/Korn shell ve- staveny povel read, napr. jednu radku ze vstupu do promenne muzete v Bourne/Korn shellu nacist povelem read promenna C shell ma specialni promennou <, napr. jednu radku ze vstupu do promenne muzete v C shellu nacist povelem set promenna=$< Vsechny tri shelly uzivaji povelu echo k zapisu hodnot promennych na vystup. Rizeni behu programu Ve vsech trech shellech existuji konstrukce if (rozhodnuti) a while (smycka), i kdyz syntaxe v Bourne/Korn shellu se oproti C shellu lisi. Krome toho jsou v kazdem shellu dostupne dalsi specificke kon- strukce pro rozhodnuti (v Bourne/Korn shellu case, v C shellu foreach). Bezpecnost behu programu Ve vsech trech shellech existuji prostredky pro zpracovani chyb; v Bourne/Korn shellu povel set -x v C shellu povel set echo a prostredky pro ladeni programu: v Bourne/Korn shellu vestaveny povel trap, v C shellu vestaveny povel onintr. 7. Shellovske scenare Shellovsky scenar (shell script) je, jak jsme jiz rekli v odst. 6.1, soubor, obsahujici konstrukce urcene k interpretaci shellem. Shell cte scenar radku po radce stejne jako to dela pri interaktivne zadavanych povelovych radkach. Proto kazda radka scenare musi byt spravna povelova radka pro shell, ktery scenar zpracovava. Plati, ze jakykoli povel, ktery muze byt zapsan v interakci na povelove radce, muze byt umisten jako samostatna radka v shellovskem scenari, a na- opak. 7.1 Vytvoreni shellovskeho scenare Protoze shellovsky scenar obsahuje pouze znakova data, muzete jej vytvorit jakymkoli editorem systemu UNICOS (vi, emacs aj.). Scenar se pak da spustit nekolika odlisnymi zpusoby, jak uvidite dale. Kdyz vytvarite proveditelny scenar (tedy scenar, ktery je spustitelny jako povel), muzete postupovat podle nasledujicich kroku: Volba jmena Jmeno souboru vaseho scenare bude vlastne jmenem povelu, kterym jej vyvolate. Proto byste meli zvolit jmeno, ktere jeste neni jmenem zadneho povelu. Zda vami zvolene jmeno_scenare neni jiz obsazeno, se dozvite v Bourne/Korn shellu povelem type jmeno_scenare a v C shellu povelem which jmeno_scenare Pridani pristupoveho prava pro provedeni Jakmile mate scenar vytvoren, pridejte pristupove pravo pro jeho provedeni povelem chmod u+x jmeno_scenare To vam umozni pozdeji provest scenar jako povel. Jeden adresar Vsechny sve proveditelne scenare muzete mit soustredeny v jedinem adresari se jmenem $HOME/bin. Pridanim jmena tohoto adresare do sve promenne PATH dosahnete toho, ze kdykoli napisete jmeno scenare jako povel, vas shell pouzije promennou PATH, scenar nalezne a spusti. Nastaveni promenne PATH Jestlize si zamerne prejete vytvorit shellovsky scenar, ktery ma stejne jmeno jako povel jiz existujici, umistete jmeno adresare se scenare ($HOME/bin) na zacatek seznamu adresaru v promenne PATH. Aktualizace hasovaci tabulky (pouze pro C shell) Aktualizujte obsah hasovaci tabulky povelem rehash (viz odst. 2.4.1). Priklad: Mozna uprava inicializacnich souboru .login a .profile: cray101% vi .login ... set path = (~/bin $path .) ... cray102% vi .profile ... PATH=$HOME/bin:$PATH:. ... cray103% 7.2 Dokumentace shellovskeho scenare Stejne jako u kterehokoli jineho typu programu plati i pro shel- lovsky scenar, ze jednim z klicu jeho udrzby je solidni interni doku- mentace. K oznacovani zacatku poznamky uvnitr scenare slouzi znak #. Poznamka se muze objevit ve scenari kdekoli. Kdyz shell precte znak #, zbytek radky ignoruje. Priklad: Nasledujici radky demonstruji vytvoreni a dokumentaci shellovskeho scenare, o nichz byla rec v poslednich dvou odstavcich. Uzivatel novak chce vytvorit scenar se jmenem nice. Nejprve si zkon- troluje, zda toto jmeno jiz neni obsazeno: cray101% which nice nice: is built into the csh cray102% which list no list in /home/novak/bin /bin /usr/bin /usr/lbin /usr/ucb . cray103% Uzivatel zjistil, ze jmeno nice je jiz obsazeno (vestaveny povel C shellu). Zvolil si tedy jmeno list, ktere je volne. cray103% vi list .... vytvoreni scenare .... cray104% cat list # syntaxe: list # list: vytiskne jmeno pracovniho adresare, # dnesni datum a soubory v pracovnim adresari pwd date ls -FC cray105% Uzivatel vytvoril scenar pomoci editoru vi, do jeho zahlavi uvedl, jak se scenar vola (syntaxe povelu) a co scenar dela (semantika povelu). cray105% chmod u+x list cray106% pwd /home/novak/bin cray107% Pridal pristupove pravo pro provadeni scenare a presvedcil se, ze jej vytvoril pod adresarem $HOME/bin. cray107% echo $PATH /home/novak/bin:/bin:/usr/bin:/usr/lbin:/usr/ucb:. cray108% cd ~/STRUKTURA1 cray109% rehash cray110% list /home/novak/STRUKTURA1 Thu Jan 5 12:22:04 MEZ 1995 a.out* data1 data2 program1.f cray111% Uzivatel novak ma umisten adresar $HOME/bin na prvnim miste v promenne PATH (i kdyz pro nalezeni scenare list z tohoto prikladu to nebylo ne- zbytne nutne) a tak mu nic nebrani, aby scenar spustil. 7.3 Provedeni shellovskeho scenare Kdyz jste shellovsky scenar vytvorili, budete jej chtit provest. System UNICOS poskytuje nekolik vseobecnych zpusobu, jak to udelat. Nejbeznejsi je vyvolat proveditelny scenar jako povel: jmeno_scenare Povel jmeno_scenare se stane podprocesem shellu, ktery jej vyvo- lava, stejne jako jine proveditelne povely. Shelly take poskytuji prostredek, ktery umoznuje specifikovat, jaky shell ma byt pro prove- ditelny scenar pouzit, primo v tomto scenari. Dosahnete toho tim, ze jako prvni radku ve vasem scenari uvedete: #!/bin/jmeno_shellu (kde jmeno_shellu je sh, ksh nebo csh). Scenar muzete take provest jako podproces s explicitne uvedenym shellem (nazyvanym subshell) na povelove radce: sh jmeno_scenare (Bourne shell) ksh jmeno_scenare (Korn shell) csh jmeno_scenare (C shell) Kazdy z techto povelu vyvola odpovidajici subshell, aby scenar provedl. Subshell skonci, kdyz dosahne konce scenare. Castym je take zpusob provest scenar jako davkovou ulohu. Systemy UNICOSu, na kterych je prostredek NQS (Network Queuing System), coz je pripad i pocitace Cray Y-MP EL ve FzU, mohou zadat scenar, aby se pro- vedl jako oddelena relace (povelem qsub nebo nekterym nadstavbovym prostredkem, ktery tento povel vyuziva). Spustena davkova uloha projde vsemi standardnimi inicializacnimi soubory a nastavi uzivatele do jeho domovskeho adresare (pokud neni zadano jinak). NQS shromazdi vystup generovany ulohou a vrati jej uzivateli, kdyz uloha skonci. O pro- stredku NQS se muzete podrobneji docist v priruckach [2] a [6]. Nekdy byva uzitecne vyuzit take moznosti spustit scenar tzv. in- line, to znamena uvnitr aktualniho shellu. Jsou tak spousteny napri- klad vsechny vase inicializacni scenare (soubory), tj. .profile (Bourne a Korn shell), .login (C shell), $ENV (Korn shell) a .cshrc (C shell). Tyto scenare nastavuji vase promenne, aliasy a funkce v ramci vaseho dialogoveho nebo davkoveho shellu. Kdyby se provedly v subshel- lu, byla by tato nastaveni ztracena. Pro spusteni scenare inline slou- zi v Bourne a Korn shellu povel . jmeno_skriptu a v C shellu povel source jmeno_skriptu Priklad 1: Povel 101 ukazuje obsah scenare. Povel 102 spousti proveditelny scenar jako povel. Povely 103 a 104 spousteji scenar s explicitne uvedenym shellem na povelove radce (subshelly). Povel 105 scenar zaradi do uvedene fronty NQS, kde bude jako davkova uloha spus- ten. Povel 106 vypise obsah vystupniho souboru z teto ulohy. cray101% cat $HOME/bin/ps_scr # syntaxe: ps_scr # ps_scr: provede povel ps s volbami -f (full process # status) a -u novak (user novak) ps -f -u novak cray102% ps_scr UID PID PPID TTY TIME COMMAND novak 55768 55760 p001 0:00 csh novak 55760 55759 p001 0:01 csh novak 55769 55768 p001 0:00 ps cray103% sh $HOME/bin/ps_scr UID PID PPID TTY TIME COMMAND novak 55760 55759 p001 0:01 csh novak 55771 55770 p001 0:00 ps novak 55770 55760 p001 0:00 sh cray104% ksh $HOME/bin/ps_scr UID PID PPID TTY TIME COMMAND novak 55772 55760 p001 0:00 ksh novak 55760 55759 p001 0:01 csh novak 55773 55772 p001 0:00 ps cray105% qsmart -q0 $HOME/bin/ps_scr .... Request 7929.cray submitted to queue: class0 cray106% cat ps_scr.o7929 .... (zpravy z prihlaseni do systemu) UID PID PPID TTY TIME COMMAND novak 55760 55759 p001 0:02 csh novak 56410 56403 ? 0:00 ps novak 56403 56402 ? 0:00 sh cray107% Priklad 2: Pri prechodu z jednoho shellu do jineho (zde z login shellu csh do ksh) vyuzijeme spusteni inicializacnich souboru (zde .profile a $ENV) inline. Po praci v Korn shellu se povelem exit vratime do C shellu a az druhym uvedenim povelu exit bychom se odhlasili od systemu. .... prace se C shellem (csh) .... cray151% cat $HOME/.profile .... PS1='! cray$ ' if tty -s then ENV=$HOME/.kshrc_inter else ENV=$HOME/.kshrc_batch fi .... export ... ENV ... PS1 ... cray152% cat $HOME/.kshrc_inter .... alias cas='date | cut -c 12-24' .... ll () { ls -l } .... cray153% ksh $ . $HOME/.profile 1 cray$ . $ENV 2 cray$ cas 14:06:45 MEZ 3 cray$ ll .... obsah pracovniho adresare v dlouhem formatu .... .... 35 cray$ exit cray154% 8. Predavani parametru shellovskym skriptum Shellovsky scenar muzete napsat tak, ze si cte parametry z pove- love radky, kdyz jej spustite jako povel. Na parametry se muzete odvo- lavat uvnitr scenare podle jejich pozice na povelove radce. Parametry predavane shellovskemu scenari jsou jeden od druheho oddeleny "prazdnym znakem", coz je mezera, tabulator atd. 8.1 Pozicni parametry Pozicni parametry odkazuji na jednotlive parametry na povelove radce. Na tyto pozicni parametry se ve scenari muzete odvolat vyuzitim syntaxe $1 (predstavuje prvni parametr na povelove radce), $2 (pred- stavuje druhy parametr) atd. Jestlize parametr povelove radky, odpovi- dajici pozicnimu parametru, na ni neni pritomen, hodnota tohoto pozic- niho parametru je prazdny retezec (""). Bourne/Korn shell vam umoznuji primy pristup k prvnim deviti pa- rametrum ($1, $2, ..., $9). Pro zpristupneni desateho, jedenacteho a dalsich musite pouzit povelu shift, o kterem se zminime v nasledujicim odstavci. C shell umoznuje primy pristup k libovolnemu parametru uvedenim cisla jeho pozice na povelove radce (tedy i $10, $11 atd.). Uvedme jeste nektere dalsi specialni shellovske promenne, ktere muzete vyuzit pri psani skritpu. 0 jmeno povelu uzite pro vyvolani scenare * retezec obsahujici vsechny pozicni parametry z po- velove radky shellovskeho scenare # pocet parametru na povelove radce scenare (pouze Bourne/Korn shell) #argv pocet parametru na povelove radce scenare (pouze C shell) Priklad: cray101% cat cvicebni #! /bin/ksh # syntaxe: cvicebni [parametr1 [parametr2]] # cvicebni: vypise jednotlive pozicni parametry a obsah # specialnich shellovskych promennych echo "1.parametr: $1" echo "2.parametr: $2" echo "Jmeno skriptu: $0" echo "Pozicni parametry: $*" echo "Pocet pozicnich parametru: $#" cray102% cvicebni program1.f data1 1.parametr: program1.f 2.parametr: data1 Jmeno skriptu: cvicebni Pozicni parametry: program1.f data1 Pocet pozicnich parametru: 2 cray103% 8.2 Povel shift Ve vsech trech shellech je vestaveny povel shift, ktery posouva parametry povelove radky. Jinymi slovy, meni puvodni druhy parametr na $1, puvodni treti parametr na $2 atd. Pozmeni take odpovidajicim zpu- sobem $* a snizi hodnotu $# (nebo $#argv). Tento povel je zvlaste dulezity v Bourne/Korn shellu, nebot dela primo pristupnym desaty parametr povelove radky pres pozicni parametr $9. Povel shift muze mit take celociselny parametr: shift n ktery udava, kolikrat se posun parametru ma provest. Po tomto povelu je tedy prvnich n parametru ztraceno. Tyto parametry by tudiz mely byt bud zpracovany nebo uschovany pred timto povelem. Priklad: cray101% cat kompilace #! /bin/ksh # syntaxe: kompilace soubor1 soubor2 soubor3 # kompilace: prelozi tri fortranske soubory # specifikovane na povelove radce echo "Preklada se: $1" cf77 -c $1 echo "Preklada se: $2" cf77 -c $2 shift echo "Preklada se: $2" cf77 -c $2 cray102% kompilace file1.f file2.f file3.f Preklada se: file1.f Preklada se: file2.f Preklada se: file3.f cray103% Podivame-li se na povel 102, je pred provedenim povelu shift tato korespondence souboru: $1 file1.f $2 file2.f $3 file3.f $# 3 zatimco po provedeni povelu shift je nasledujici: (ztracen) file1.f $1 file2.f $2 file3.f $# 2 9. Vstup/vystup V teto kapitole se zminime o tom, jak psat shellovske scenare, ktere s vami mohou komunikovat. Uvnitr shellu jsou castymi uzitecnymi prostredky presmerovani standardnich souboru a roura. Zde uvedeme prostredek bezny z programovacich jazyku: nacteni vstupu do promennych a vystup hodnot promennych. 9.1 Vstup Nejprve tedy jak nacist vstup do shellovskeho scenare. V Bourne/Korn shellu vam k tomu slouzi povel read, kterym muzete nacist jednu radku standardniho vstupu do jedne nebo vice lokalnich promennych: read promenna1 [promenna2 ...] Jestlize je uvedena pouze jedna promenna, nacte se do ni cela radka standardniho vstupu. Jestlize je uvedeno promennych vice, prvni slovo vstupni radky se ulozi do promenne1, druhe slovo do promenne2 a tak dale az do promenne_posledni se ulozi zbytek vstupni radky. V C shellu se vam do specialni promenne < ulozi nasledujici radka standardniho vstupu. Abyste do lokalni promenne dostali radku stan- dardniho vstupu, pouzijte povel set promenna=$< 9.2 Vystup Nyni jak dostat potrebny vystup ze shellovskeho scenare. Ve vsech trech shellech k tomu muzete pouzit povel echo. V Bourne/Korn shellu je format tohoto povelu echo vystupni_parametry Vystupni_parametry casto obsahuji shellovske substituce, ktere jsou rozvinuty pred tim, nez je radka poslana na vystup. Jestlize po- sledni vystupni_parametr konci retezcem \c , povel echo ponecha kurzor na konci radky (nevypise znak "nova radka"). V tomto pripade by tedy retezec \c mel byt uzavren bud v apostrofech nebo uvozovkach, aby zpetne lomitko nebylo interpretovano shellem jako specialni znak (viz odst.4.2). Povel echo s retezcem \c byva ve scenari uzivan nejcasteji tehdy, kdyz je uzivatel zadan o nejaky vstup. V C shellu je format povelu echo [-n] vystupni_parametry Volba -n ma vyznam "zadnou novou radku" a plni tedy stejnou funkci jako \c v povelu echo v Bourne/Korn shellu. Priklad: cray101% cat presun #! /bin/ksh # syntaxe: presun [odkud [kam]] # presun: presouva soubor odkud do souboru kam; # neuvedene parametry jsou skriptem vyzadany odkud=$1 kam=$2 if [ "$odkud" = "" ] then echo "Zadejte soubor odkud: \c" read odkud fi if [ "$kam" = "" ] then echo "Zadejte soubor kam: \c" read kam fi mv $odkud $kam cray102% ls -F presun *.out a.out* presun* cray103% presun a.out Zadejte soubor kam: b.out cray104% presun Zadejte soubor odkud: b.out Zadejte soubor kam: c.out cray105% !-3 ls -F presun *.out c.out* presun* cray106% 10. Vystupni stav a shellovska rozhodnuti Na konci sveho provedeni vraci kazdy povel UNICOSu procesu, ktery jej vyvolal, stavove cislo. Toto cislo se nazyva vystupni stav (exit status). Vystupni stav indikuje, zda povel (nebo program) probehl uspesne nebo ne. Konvenci je stanoveno, ze vystupni stav rovny nule je uzivan pro indikaci uspesneho ukonceni, nenulovy vystupni stav pak in- dikuje nejakou chybu pri provadeni povelu (programu). Napriklad povel mv vrati nenulovy vystupni stav, jestlize prejme- novani (presun) souboru z nejakeho duvodu selhalo (nemoznost pristupu k puvodnimu souboru, nemoznost vytvoreni ciloveho souboru, nedostatec- ny pocet parametru v povelu aj.). Typ chyby muze byt klasifikovan prirazenim odlisnych trid chyb jednotlivym nenulovym hodnotam vystupniho stavu. Bourne/Korn shell nastavuje hodnotu vystupniho stavu posledniho provedeneho povelu na popredi v promenne ?, C shell pak v promenne status. Zjistit vystupni stav tudiz muzete v Bourne/Korn shellu pove- lem echo $? v C shellu povelem echo $status V roure nebo v jinak seskupenych povelech je hodnotou techto pro- mennych vystupni stav posledniho povelu. Vystupni stav ve vsech trech shellech uzivaji povely pro rozhod- nuti (if) a smycky (while aj.) pro vykonani logickych (booleovskych, binarnich) rozhodnuti. V Bourne/Korn shellu reprezentuje uspesny vystupni stav (nula) logickou hodnotu pravda (true), neuspesny vystupni stav (nenulova hod- nota) reprezentuje logickou hodnotu nepravda (false). V C shellu se pouzivaji k testum vystupniho stavu logicke vyrazy nejcasteji s aritmetickymi operatory == ("rovna se") a != ("nerovna se"). 10.1 Nastaveni vystupniho stavu ve skriptech Shell, stejne jako kterykoli jiny proces, nastavuje vystupni stav, kdyz konci svoje provedeni. Pro povelovy nebo davkovy scenar konci shell s nim spojeny jednim z techto tri zpusobu: abort Jestlize se scenar ukonci v dusledku nejake vnitr- ni chyby, jeho vystupnim stavem je vystupni stav posledniho povelu (tedy povelu, ktery predcasne ukonceni scenare zpusobil). end Jestlize se scenar provede az do konce, jeho vy- stupnim stavem je vystupni stav posledniho povelu ve scenari. exit Jestlize scenar narazi na povel exit, jeho vystup- nim stavem je hodnota nastavena timto povelem exit. V Bourne/Korn shellu je syntaxe povelu exit [stav] v C shellu exit [(stav)] Shell tedy skonci s vystupnim stavem stav. Pokud stav neni uveden, skonci s vystupnim stavem po- sledniho povelu pred exit. Priklad: cray101% mv file1 file2 cray102% echo $status 0 cray103% mv file1 file2 mv: cannot access file1 cray104% echo $status 2 cray105% ksh $ if mv file1 file2 > then echo mv se povedlo > else echo mv se nepovedlo > fi mv: cannot access file1 mv se nepovedlo $ if mv file2 file1 > then echo mv se povedlo > else echo mv se nepovedlo > fi mv se povedlo $ cat exitstat exit $1 $ exitstat 5 ; echo $? 5 $ exitstat ; echo $? 0 $ exit cray106% 10.2 Vyhodnocovani logickych vyrazu a aritmetika K tomu, abyste mohli pouzivat programove konstrukce pro rozhodnu- ti a smycky, je zapotrebi mit moznost vyhodnocovat tzv. logicke vyrazy (logical expressions) a provadet alespon zakladni aritmeticke operace. 1) V Bourne/Korn shellu je k dispozici povel test, ktery vyhodno- cuje logicky vyraz a vraci odpovidajici vystupni stav. Povel test ma dva ekvivalentni formaty: test logicky_vyraz [ logicky_vyraz ] Obvykle se pouziva druhy format pro jeho strucnost, mezery kolem zavorek jsou povinne. Povel neprodukuje zadny vystup, jeho jedinym ucelem je vyhodnotit logicky_vyraz. Povel test vraci vystupni stav 0 pro pravdivy logicky_vyraz a vystupni stav 1 pro nepravdivy logicky_vyraz. Povel test vam umoznuje vyhodnocovat nasledujici typy podminek (u kazdeho typu je uvedeno nekolik moznosti, podrobnejsi in- formace nalezne zajemce napr. v manualu [5]): . Informace o souborech (napr. existence, velikost, pristupova prava, typ) [ -d soubor ] pravda, jestlize soubor existuje a je to adresar [ -f soubor ] pravda, jestlize soubor existuje a je to obycejny soubor [ -r soubor ] pravda, jestlize soubor existuje a je pro vykonavatele povelu test citelny [ -s soubor ] pravda, jestlize soubor existuje a je neprazdny [ -x soubor ] pravda, jestlize soubor existuje a je pro vykonavatele povelu test provedi- telny . Informace o retezcich (napr. delka, rovnost, relacni operace) [ -z retezec ] pravda, jestlize delka retezce je nu- lova [ -n retezec ] pravda, jestlize delka retezce je ne- nulova [ retezec1 = retezec2 ] pravda, jestlize jsou oba retezce identicke [ retezec1 != retezec2 ] pravda, jestlize retezce nejsou iden- ticke . Numericka srovnani pomoci relacnich operatoru [ n1 -eq n2 ] pravda, jestlize se cisla n1 a n2 rovnaji [ n1 -gt n2 ] pravda, jestlize n1 je vetsi nez n2 [ n1 -le n2 ] pravda, jeslize n1 je mensi nebo rov- no n2 Numericka rovnost neni shodna s rovnosti retezcu, protoze numericka rovnost ignoruje nevyznamne nuly a pocatecni nebo koncove mezery. Slozitejsi logicke vyrazy lze vytvaret z jednodussich pouzitim logickych operatoru -a ("a zaroven", konjunkce), -o ("nebo", disjunk- ce) a ! ("ne", negace) a pripadne zavorek predchazenych zpetnym lomit- kem (\( a \)). Priklad: $ ls -l data1 -rw------- 1 novak g75 355 Jan 10 14:30 data1 $ [ -s data1 ] && echo soubor data1 existuje a je neprazdny soubor data1 existuje a je neprazdny $ A=06 $ [ "$A" = 6 ] && echo identicke retezce $ [ "$A" != 6 ] && echo neidenticke retezce neidenticke retezce $ [ "$A" -eq 6 ] && echo numericka rovnost numericka rovnost $ cat presun1 #! /bin/ksh # syntaxe: presun1 # presun1: presune f1 na f2, jen kdyz: # 1) f1 existuje a je citelny # 2) f2 neexistuje nebo je prazdny nebo je to adresar if [ \( -r f1 \) -a \( ! -s f2 -o -d f2 \) ] then mv f1 f2 else echo presun f1 nemuze byt proveden fi $ presun1 $ ls -F f* f2 $ presun1 presun f1 nemuze byt proveden $ Pro vyhodnocovani aritmetickych vyrazu v Bourne shellu lze pouzit povel expr, ktery rozeznava zakladni aritmeticke operatory (+, -, *, /) a operator modulo (%) (zbytek po celociselnem deleni). Povel expr pracuje pouze s celymi cisly. Ve spojeni s nim muzete vyuzit povelove substituce pro prirazeni hodnoty vyrazu promenne. Priklad: $ A=7 $ B=3 $ VYRAZ=`expr $A * $B - 2` $ echo $VYRAZ 19 $ V Korn shellu je vhodne pouzit pro vyhodnocovani aritmetickych vyrazu vestaveneho povelu let (viz kap. 13). 2) C shell ma nekolik prostredku pro vyhodnocovani podminek, kte- re se uzivaji v programovacich konstrukcich pro rozhodnuti a smycky; podminkami jsou ciselne nebo logicke vyrazy, podobne vyrazum v jazyku C. K dispozici jsou aritmeticke operatory a relace (+, -, *, /, >, <, >= atd.), tzv. dodatecne aritmeticke a retezove operatory (== a != "rovna se" a "nerovna se" pro cisla nebo retezce); logicke operatory (||, &&, !), podminky pro soubory (vetsina je shodna po formalni i vy- znamove strance s parametry povelu test). Je take mozne testovat uspesnost ukonceni povelu pomoci zapisu { povel } V C shellu je k dispozici funkce @, kterou lze pouzit pro vyhod- nocovani aritmetickych vyrazu (pracuje s celymi cisly) nebo logickych vyrazu. Priklad: cray101% ls -F f* f2 cray102% set A=6 cray103% @ VYSLEDEK=((-d f2) || ($A == 2 * 3)) cray104% echo $VYSLEDEK 1 cray105% Na povelove radce 103 ukladame do promenne VYSLEDEK hodnotu lo- gickeho vyrazu: "Je soubor f2 adresarem nebo se hodnota promenne A rovna aritmeticke hodnote 2*3 ?" Protoze je hodnota teto alternativy pravdiva, ulozila se do promenne VYSLEDEK jednicka (v opacnem pripade by se ulozila nula). 11. Prostredky pro rizeni chodu programu Vsechny tri shelly poskytuji programove konstrukce pro vykonani automatickych rozhodnuti a pro opakovani posloupnosti povelu v cyk- lech. V Korn shellu je navic konstrukce umoznujici snadne programovani menu. 11.1 Konstrukce pro rozhodnuti V tomto odstavci se seznamite s konstrukci if, ktera je k dispo- zici ve vsech trech shellech, s konstrukci case, ktera je v Bourne/Korn shellu, a s konstrukci switch, ktera je v C shellu. 11.1.1 Konstrukce if Tato konstrukce je podobna prikazum if v jinych programovacich jazycich. Jeji syntaxe v Bourne/Korn shellu je tato: if podminkove_povely then pravda_povely [elif podminkove_povely2 then pravda_povely2 ...] [else nepravda_povely] fi Pravda_povely se provedou, jestlize uspesne skoncil posledni z podminkovych_povelu (jeho vystupni stav je nula). Vetve pro dalsi roz- hodnuti mohou byt pridany jednou nebo vice klauzulemi (tj. syntaktic- kymi castmi konstrukce s prirazenym vyznamem) elif (vyznam "else if"). Vetev pro "vsechny podminky jsou nepravdive" je dostupna pres klauzuli else. Nezapomente, ze kazda konstrukce if konci klicovym slovem fi. V mnoha pripadech se pouziva pouze jediny podminkovy_povel, kterym byva povel test obvykle zapsany "zavorkovou" syntaxi, takze nejjednodussi podoba konstrukce if je if [ logicky_vyraz ] then pravda_povely fi Pokud chcete klicove slovo then zapsat na stejnou radku jako pod- minkove_povely, musite za nimi uvest strednik, tedy napr. if [ logicky_vyraz ]; then pravda_povely fi Priklad: cray101% cat comp_fC #! /bin/ksh # syntaxe: comp_fC zdrojovy_soubor # comp_fC: kompiluje zdrojovy soubor ve fortranu nebo v C # a nasledne jej spousti suffix= `echo $1 | cut -f2 -d.` if [ "$suffix" = c ] then cc $1 && a.out elif [ "$suffix" = f ] then cf77 $1 && a.out else echo "$0: '$1' neni ani fortran ani C." exit 10 fi cray102% ls -F comp_fC comp_fC* cray103% cat test.c main () { printf("C\n"); } cray104% comp_fC test.c C cray105% cat test.f program test print *,"fortran" end cray106% comp_fC test.f fortran cray107% comp_fC xxx comp_fC: 'xxx' neni ani fortran ani C. cray108% V C shellu je syntaxe konstrukce if nasledujici: if (logicky_vyraz) then pravda_povely [elseif (logicky_vyraz2) then pravda_povely2 ...] [else nepravda_povely] endif V nejjednodussim pripade je mozne uvest pouze if (logicky_vyraz) pravda_povel Oproti Bourne/Korn shellu se konstrukce if v C shellu lisi krome od- lisne syntaxe predevsim tim, ze logicke_vyrazy se vyhodnocuji primo, zatimco v Bourne/Korn shellu neprimo pres povel test. 11.1.2 Konstrukce case (Bourne/Korn shell) Opet nic neobvykleho oproti beznym programovacim jazykum, v nichz byvaji povely case nebo switch. Syntaxe konstrukce case v Bourne/Korn shellu je nasledujici: case substitucni_retezec in vzor1[|vzor1B ...]) seznam_povelu1;; [vzor2[|vzor2B ...]) seznam_povelu2;; ...] [ *) implicitni_seznam_povelu;;] esac Konstrukce case provede ten seznam_povelu, ktery je spojen s prv- nim vzorem, jenz se shoduje se substitucnim_retezcem. Substitucni_retezec byva casto reprezentovan substituci promenne. Vzory mohou obsahovat metaznaky (*, ?, [, ]), ktere maji stejny vyznam jako pri generovani jmen souboru. Tak napr. * pouzita jako posledni vzor se shoduje s jakymkoli substitucnim_retezcem, ktery nebyl v pre- deslych vzorech nalezen. Muzete spojit nekolik vzoru s jedinym seznamem_povelu tim, ze je navzajem oddelite znakem svisla cara (|). Povsimnete si take, ze pravou kulatou zavorkou ) konci kazdy se- znam vzoru, dvema stredniky (;;) konci kazdy seznam_povelu a klicovym slovem esac konci cela konstrukce case. Priklad: Scenar comp_fC_2 resi stejnou ulohu jako comp_fC z minu- leho odstavce; take obsah souboru test.c a test.f je tyz. cray101% cat comp_fC_2 #! /bin/ksh # syntaxe: comp_fC_2 zdrojovy_soubor # comp_fC_2: kompiluje zdrojovy_soubor ve fortranu nebo v C # a nasledne jej spousti case "$1" in *.c) cc $1 && a.out;; *.f) cf77 $1 && a.out;; *) echo "$0: $1 neni ani fortran ani C". exit 10;; esac cray102% ls -F comp_fC_2 comp_fC_2* cray103% comp_fC_2 test.c C cray104% comp_fC_2 test.f fortran cray105% comp_fC_2 xxx comp_fC_2: xxx neni ani fortran ani C. cray 106% 11.1.3 Konstrukce switch (C shell) Konstrukce switch v C shellu pripomina konstrukci case v Bourne/Korn shellu. Jeji syntaxe je: switch (substitucni_retezec) case vzor1: [seznam_povelu1] [breaksw] [case vzor2: [seznam_povelu2] [breaksw] ...] [default:] implicitni_seznam_povelu] endsw Obdobne jako case take konstrukce switch provede ten seznam_povelu, ktery je spojen s prvnim vzorem, jenz se shoduje se substitucnim_retezcem. Substitucni_retezec byva casto reprezentovan substituci promenne. V konstrukci switch vsak pokracuje provadeni seznamu_povelu, dokud se nenarazi na klicove slovo breaksw. Kazdy vzor nasledujici za klicovym slovem case muze obsahovat metaznaky (*, ?, [, ]), ktere maji stejny vyznam jako pri generovani jmen souboru. Kdyz chcete spojit nekolik vzoru s jedinym seznamem_povelu, umistete jedno- duse nekolik "prazdnych" radek, obsahujicich pouze case vzor: (tedy bez povelu a bez slova breaksw), pred prislusny seznam_povelu. Povsimnete si, ze znakem dvojtecka (:) konci kazdy vzor, slovem breaksw konci provadeni seznamu_povelu a klicovym slovem endsw konci cela konstrukce switch. Priklad: cray101% cat retezec_t #! /bin/csh # syntaxe: retezec_t # retezec_t: testuje retezec zadany ze stdin echo -n "Zadejte retezec: " set retezec=$< switch (retezec) case [A-Z]*: echo "Retezec zacina velkym pismenem." breaksw case [0-9]*: case *[0-9]: echo "Retezec zacina nebo konci cislici." breaksw case [a-z][a-z][a-z]: echo "Retezec sestava ze 3 malych pismen." breaksw default: echo "Nejaky jiny retezec." endsw cray102% retezec_t Zadejte retezec: abc Retezec sestava ze 3 malych pismen. cray103% retezec_t Zadejte retezec: 1q Retezec zacina nebo konci cislici. cray104% retezec_t Zadejte retezec: bALET Nejaky jiny retezec. cray105% 11.2 Konstrukce pro programove cykly V tomto odstavci probereme konstrukce, ktere vam umoznuji opako- vat posloupnosti povelu. Jsou to konstrukce while, ktera je ve vsech trech shellech, konstrukce until a for, ktere jsou v Bourne/Korn shellu, a konstrukce foreach, ktera je v C shellu. 11.2.1 Konstrukce while Tato konstrukce vam umoznuje opakovat nejakou posloupnost povelu, pokud je splnena urcita podminka. Jeji syntaxe v Bourne/Korn shellu je nasledujici: while podminkove_povely do seznam_povelu done Seznam_povelu je v cyklu provaden, pokud posledni z podminko- vych_ povelu skonci uspesne (tedy jeho vystupni stav je nula). Stejne jako u konstrukce if byvaji velmi casto podminkove_povely reprezento- vany jedinym povelem test: while [ logicky_vyraz ] do seznam_povelu done Priklad: cray101% cat comp_fC_3 #! /bin/ksh # syntaxe: comp_fC_3 [seznam_zdrojovych_souboru] # comp_fC_3: kompiluje zdroje_soubory ve fortranu nebo v C, # uvedene na povelove radce, a nasledne je spou- # sti. while [ "$#" -ne 0 ] do echo "Kompilace: $1" comp_fC_2 $1 shift done cray102% comp_fC_3 test.c xxx test.f Kompilace: test.c C Kompilace: xxx ./comp_fC_2: 'xxx' neni ani fortran ani C. Kompilace: test.f fortran cray103% V C shellu je syntaxe konstrukce while tato: while (logicky_vyraz) seznam_povelu end Logicky_vyraz je zde opet vyhodnocen na rozdil od Bourne/Korn shellu primo. 11.2.2 Konstrukce until (Bourne/Korn shell) Tato konstrukce je dualni ke konstrukci while v tom smyslu, ze posloupnost povelu se opakuje tak dlouho, dokud neni splnena testovaci podminka. Konstrukce je dostupna pouze v Bourne/Korn shellu a jeji syntaxe je tato: until podminkove_povely do seznam_povelu done Seznam_povelu je v cyklu provaden tak dlouho, dokud posledni z podminkovych_povelu neskonci uspesne (tedy jeho vystupni stav je nu- la). Priklad: cray101% cat comp_fC_4 #! /bin/ksh # syntaxe: comp_fC_4 # comp_fC_4: kompiluje a spousti programy ve fortranu a C, # ktere se mu v interakci postupne na vyzvu zada- # vaji. until echo "Zadejte zdrojovy soubor: \c" read source [ "$source" = "" ] do comp_fC_2 $source done cray102% comp_fC_4 Zadejte zdrojovy soubor: test.f fortran Zadejte zdrojovy soubor: xxx ./comp_fC_2: 'xxx' neni ani fortran ani C. Zadejte zdrojovy soubor: cray103% 11.2.3 Konstrukce for (Bourne/Korn shell) Konstrukce for v Bourne/Korn shellu je urcena pro opakovane pro- vedeni posloupnosti povelu v pripadech, kdy pocet techto opakovani je znam jiz pred pocatkem cele konstrukce. Jeji syntaxe je nasledujici: for ridici_promenna_cyklu [ in seznam_slov ] do seznam_povelu done Seznam_povelu je postupne proveden pro kazde slovo ze seznamu_slov; tato slova jsou navzajem oddelena "prazdnymi znaky" (me- zerami nebo tabulatory). V prvnim pruchodu je hodnotou ridici_pro- menne_cyklu prvni slovo ze seznamu_slov, ve druhem pruchodu je jeji hodnotou druhe slovo atd., dokud neni seznam_slov vycerpan. Hodnota teto ridici_promenne_cyklu je obvykle pouzita v seznamu_povelu, cimz se meni pusobeni techto povelu (napr. na jine objekty). Seznam_slov vetsinou obsahuje shellovskou substituci promenne, metaznaky pro generovani jmen souboru nebo povelovou substituci. Shell tyto akce vykona pred provedenim konstrukce cyklu for. Povsimnete si, ze klauzule in seznam_slov je nepovinna. Jestlize ji vynechate, seznam_povelu se provede pro kaz- dy parametr povelove radky scenare, jehoz je tato konstrukce soucasti. Jinymi slovy, $* (seznam vsech parametru) je implicitni hodnotou seznamu_slov. Priklad: cray101% cat comp_all #! /bin/ksh # syntaxe: comp_all # comp_all: kompiluje vsechny zdrojove soubory fortranu nebo # C v pracovnim adresari a nasledne je spousti for source in *.[cf] do echo "Kompilace: $source" comp_fC_2 $source done cray102% comp_all Kompilace: test.c C Kompilace: test.f fortran cray103% cat comp_fC_5 #! /bin/ksh # syntaxe: comp_fC_5 [seznam_zdrojovych_souboru] # comp_fC_5: kompiluje zdrojove soubory fortranu nebo C, # uvedene na povelove radce a nasledne je spousti for source do echo "Kompilace: $source" comp_fC_2 $source done cray104% comp_fC_5 test.f xxx Kompilace: test.f fortran Kompilace: xxx ./comp_fC_2: 'xxx' neni ani fortran ani C. cray105% 11.2.4 Konstrukce foreach (C shell) Konstrukce foreach v C shellu je velmi podobna konstrukci for v Bourne/Korn shellu. Jeji syntaxe je nasledujici: foreach ridici_promenna_cyklu (seznam_slov) seznam_povelu end Vsechny metavyrazy zde maji stejny vyznam jako u konstrukce for v Bourne/Korn shellu. Jedinou vyjimkou je povinne uvedeni seznamu_slov. Priklad: cray101% cat cwl #! /bin/ksh # syntaxe: cwl # cwl: vypise kalendar roku '95, do systemu prihlasene uzi- # vatele a seznam souboru v pracovnim adresari foreach i ( "cal 1995" who "ls -FC" ) $i | pg end cray102% cwl .... vystup povelu cal, who a ls .... cray103% 11.3 Konstrukce select pro programovani menu (Korn shell) Korn shell poskytuje moznost snadne pripravy menu povelu. Kon- strukce select vezme slova ze seznamu_slov jako parametry (stejne jako konstrukce for), automaticky jim priradi cisla (ocisluje slova od jed- ne vyse) a seznam techto ocislovanych slov zobrazi. Pak vezme numeric- ky vstup od uzivatele, prelozi jej do odpovidajiciho slova a provede seznam_povelu s promennou, jejiz hodnotou se stane toto slovo. Syntaxe konstrukce select je nasledujici: select promenna in seznam_slov do seznam_povelu done Konstrukce select pracuje v nasledujicich krocich: 1) Zobrazi ocislovana slova ze seznamu_slov v jednom nebo vice sloup- cich na obrazovku vaseho terminalu. Pocet techto sloupcu je urcen pomoci dvou shellovskych promennych prostredi, LINES a COLUMNS, ktere obsahuji pocet radek, resp. sloupcu, zobrazitelnych na vasem terminalu. 2) Zobrazi obsah specialni promenne PS3, coz je tzv. prompt promenna (prompt variable), do niz muzete ulozit libovolny text. 3) Precte si vasi odpoved z klavesnice (stdin) a zapamatuje si ji ve specialni shellovske promenne REPLY. 4) Jestlize je tato odpoved shodna s nekterym cislem v menu, select priradi promenne slovo u tohoto cisla a provede povely ze seznamu_povelu. Jestlize je odpoved prazdna (stiskli jste pouze klavesu ), menu a prompt se zopakuji. Jestlize je odpoved neprazdna, ale neshodna s kterymkoli cislem v menu, promenna je na- stavena na prazdny retezec a provedou se povely ze seznamu_povelu. 5) Cely tento cyklus se opakuje, dokud se nenarazi na povel break, exit nebo return v seznamu_povelu. (O povelu exit byla jiz zminka v odst.10.1, povely break a return jsou specialni povely Korn shellu, o jejichz vyznamu se lze docist napr. v popisu povelu ksh v manualu [4].) Priklad: cray101% cat menu #! /bin/ksh # syntaxe: menu # menu: nabizi: 1) vypis kalendare pro zvoleny rok # 2) aktualni datum a cas # 3) obsah pracovniho adresare # 4) vypis uzivatelu prihlasenych do systemu # 5) opusteni skriptu PS3=" Zadejte volbu: " select VOLBA in calendar date listing who quit do case $VOLBA in calendar) print "Pro jaky rok chcete kalendar?" read YEAR print "Stisknete po kazde obrazovce" cal $YEAR | pg;; date) print "Ted je:" date;; listing) print "Pracovni adresar:" pwd ls -CF | pg;; who) print "Prihlaseni uzivatele:" who | pg;; quit) print "Skript konci! Ahoj." exit 0;; *) print "Zadejte pouze jedno z cisel 1 az 5.";; esac done cray102% menu 1) calendar 2) date 3) listing 4) who 5) quit Zadejte volbu: 1 Pro jaky rok chcete kalendar? 1995 Stisknete po kazde obrazovce. 1995 Jan .... S M Tu W Th F S .... 1 2 3 4 5 6 7 .... 8 9 10 11 12 13 14 .... 15 16 17 18 19 20 21 .... 22 23 24 25 26 27 28 .... 29 30 31 .... .... .... (EOF): Zadejte volbu: 2 Ted je: Wed Jan 18 10:27:21 MEZ 1995 Zadejte volbu: 3 Pracovni adresar: /usr/home/novak/STRUKTURA1 a.out* data1 data2 program1.f (EOF): Zadejte volbu: 9 Zadejte pouze jedno z cisel 1 az 5. Zadejte volbu: 5 Skript konci! Ahoj. cray103% 12. Prostredky pro zajisteni bezpecneho provadeni skriptu V tomto odstavci se zminime o prostredcich pro zpracovani chyb a o ladicich prostredcich pro bezpecne provadeni vasich shellovskych scenaru. 12.1 Prostredky pro zpracovani chyb Shellovsky scenar muze vyzadovat bud osetreni internich chyb nebo preruseni signalem. 1. Interni chyby Na provadeni scenare a generovani chybovych hlaseni muze mit vliv kterykoli z nasledujicich typu chyb. Podprocesy Jakykoli podproces, bezici proveditelny povel, muze generovat chybova hlaseni a vratit nenulovy stav, na coz by mel shell reagovat. Zpracovani povelove radky Pred tim, nez je kterakoli povelova radka vykonana, muze na ni shell odhalit chyby, jako napriklad presmerovani standardniho vstupu na neexistujici soubor apod. Shell tuto radku neprovede, ale vyda chy- bovou zpravu a nastavi nenulovy vystupni stav. Vestaveny povel Chyba ve vestavenem povelu v Bourne a C shellu pri provadeni scenare zpusobi, ze shell provadeni scenare prerusi, vyda chybovou zpravu a nastavi nenulovy vystupni stav. Chyba ve vestavenem povelu v Korn shellu pri provadeni scenare zpusobi, ze shell generuje chybovou zpravu a nastavi nenulovy vystupni stav. Provadeni scenare vsak pokracuje. Syntaxe Syntakticke chyby, jako napr. chybejici nebo chybne zapsane kli- cove slovo, zpusobi preruseni scenare pod jakymkoli shellem. Shell ge- neruje chybovou zpravu a nenulovy vystupni kod. Muzeme tedy shrnout: scenare v Bourne a C shellu se prerusi, kdyz dojde k chybe u vestaveneho povelu nebo k syntakticke chybe, v Korn shellu se scenar prerusi pouze pri vyskytu syntakticke chyby. Priklad: $ cat err #! /bin/ksh # syntaxe: err # err: demonstruje popsane typy chyb echo CHYBA V PODPROCESU if cf77 zadny.f then a.out fi echo vystupni stav = $? echo CHYBA PRI ZPRACOVANI POVELOVE RADKY grep xxx . p p 3 p SIGQUIT p "Quit": ukonci proces bezici na popredi a p p p p poridi vypis pameti do souboru core, a to p p p p bezprostredne po stisku kombinace klaves p p p p . p p 9 p SIGKILL p "Kill": ukonci proces; tento signal nemu- p p p p ze byt zachycen nebo ignorovan. p p 15 p SIGTERM p "Terminate": ukonci proces; je to impli- p p p p citni signal povelu kill. p p 26 p SIGCPULIM p "CPU limit": ukonci proces; je to signal p p p p zaslany kteremukoli procesu, ktery pre- p p p p krocil svuj limit casu zakladni jednotky. p m--------------------------------------------------------------------] Bourne a Korn shell umoznuji uzivateli pres povel trap definovat, jaka akce ma byt provedena, kdyz je nejaky signal prijat. Syntaxe po- velu je nasledujici: trap ['seznam_povelu'][seznam_signalu] Kdyz jsou jak seznam_povelu tak seznam_signalu zadany, povel trap definuje seznam_povelu jako akci, ktera ma byt provedena pri prijeti nektereho signalu ze seznamu_signalu. Seznam_povelu musi byt jediny parametr, a proto je uzavren v apostrofech. Signaly v povelu trap mohou byt zadany bud svymi cisly nebo lite- raly, ktere vzniknou odstranenim prefixu SIG z jejich jmen. Scenar v C shellu nemuze zpracovat signaly ve vseobecnosti, ale muze zachytit a zpracovat terminalove preruseni (signal 2) pomoci ve- staveneho povelu onintr. Podrobnosti naleznete v manualu [4]. Priklad: cray101% cat trapper #! /bin/ksh # syntaxe: trapper # trapper: demonstruje pouziti povelu trapp trap 'echo zachyceno interrupt' INT trap 'echo zachyceno quit; exit 5' QUIT trap 'echo zachycen povel kill' 15 trap 'echo zachycen povel kill -9' 9 # chybny trap while [ 0 = 0 ] do echo 'usnu \c' sleep 3000 done cray102% trapper usnu zachyceno interrupt usnu trapper [11]: 87978 Quit (coredump) zachyceno quit cray103% trapper & [1] 87985 cray104% usnu kill %1 trapper[11]: 87986 Terminated zachycen povel kill usnu cray105% jobs [1] + Running trapper cray106% kill -9 %1 [1] Killed trapper cray107% jobs cray108% Ve scenari trapper jsme signaly 2 a 3 zadali literaly INT a QUIT, zatimco signaly 9 a 15 jsme pro demonstarci alternativni moznosti za- dali cisly. Doporucujeme vyuzivat literalu, nebot poukazuji na vyznam signalu. 12.2 Ladici prostredky Shelly poskytuji nektere uzitecne prostredky po odladeni scenaru. Jsou to nektere volby povelu sh, ksh a csh, vestavene povely set a unset a nastaveni v povelu trap. 12.2.1 Shellovske volby pro ladeni Existuji dva ladici prostredky, ktere muzete vyvolat zapsanim volby do povelu sh, ksh nebo csh. Vystup pri chybe Ve vsech trech shellech je dostupny prostredek, ktery zpusobi, ze shellovsky scenar je prerusen, jestlize se objevi jakykoli typ chyby nebo nenulovy vystupni stav. Tento prostredek je zvlaste uzitecny v prvnich fazich ladeni scenare, kdy muzete postupne opravovat jednotli- ve chyby a vyhnete se nakupeni chybovych zprav z ruznych mist vaseho scenare. Nejjednodussi cestou, jak vyvolat tento prostredek, je uvest skript jako parametr prislusneho povelu s volbou -e: sh -e skript (Bourne shell) ksh -e skript (Korn shell) csh -e skript (C shell) Opis provadenych povelu Vsechny tri shelly maji prostredek, ktery zajisti opis kazde zpracovavane povelove radky vaseho scenare pred jejim provedenim. Ten- to prostredek vam umoznuje presvedcit se, zda substituce neposkytuji nejake neocekavane nebo nespravne hodnoty ve zpracovavane povelove radce. Opis pro libovolny scenar muzete zajistit volbou -x v povelech sh, ksh nebo csh. Casto byva uzitecne mit tento opis zpracovavanych povelu "zapnut" v ramci jednoho scenare pouze na nekterych mistech. Pro tuto manipulaci slouzi nasledujici povely: Opis zapnut Opis vypnut Bourne/Korn shell set -x set +x C shell set echo unset echo Priklad: $ cat err2 #! /bin/ksh # syntaxe: err2 # err2: demonstruje vypis pri chybe cf77 zadny.f echo vystupni stav = $? a.out $ err2 cft77-33 cf77: ERROR Unable to read file - zadny.f cft77-25 cf77: 1 CFT77 control statement errors occured. cft77-26 cf77: Compilation aborted. vystupni stav = 1 ./err2[6]: a.out not found $ ksh -e err2 cft77-33 cf77: ERROR Unable to read file - zadny.f cft77-25 cf77: 1 CFT77 control statement errors occured. cft77-26 cf77: Compilation aborted. $ echo $? 1 $ cat err3 #! /bin/ksh # syntaxe: err3 # err3: demonstruje opis provadenych povelu set -x if cf77 zadny.f then a.out fi set +x echo vystupni stav = $? $ err3 + cf77 zadny.f cft77-33 cf77: ERROR Unable to read file - zadny.f. cft77-25 cf77: 1 CFT77 control statement errors occured. cft77-26 cf77: Compilation aborted. vystupni stav = 0 $ 12.2.2 Nastaveni v povelu trap Nektera specialni nastaveni v povelu trap zajisti reakci na "vnitrni stav scenare". (V odst.12.1 jsme tento povel vyuzili v sou- vislosti se zpracovavanim externe generovanych signalu.) Uvedme dve nejdulezitejsi nastaveni: Vystupni preruseni (v Bourne/Korn shellu) Vystupni preruseni nebo tzv. "preruseni pri nule" je vyvolano po- velem trap 'seznam_povelu' 0 Po nastaveni tohoto preruseni se seznam_povelu vyvola, kdykoli scenar skonci. Preruseni pri chybe (pouze v Korn shellu) V Korn shellu je mozne nastavit preruseni pri chybe povelem trap 'seznam_povelu' ERR Po nastaveni tohoto preruseni se seznam_povelu provede pri vysky- tu jakehokoli typu chyby nebo nenuloveho vystupniho stavu. Jestlize je uvedena volba -e (vystup pri chybe), provede se pri chybe seznam_pove- lu a scenar se ukonci. Priklad: cray101% cat err4 #! /bin/ksh # syntaxe: err4 # err4: demonstruje vystupni preruseni trap 'echo koncovy vystupni stav = $?' 0 cp zadny_soubor nikam mv zadny_soubor nikam cray102% err4 cp: cannot access zadny_soubor mv: cannot access zadny_soubor koncovy vystupni stav = 2 cray103% cat err5 #! /bin/ksh # syntaxe: err5 # err5: demonstruje preruseni pri chybe trap 'echo chybovy vystupni stav = $?' ERR cp zadny_soubor nikam mv zadny_soubor nikam cray104% err5 cp: cannot access zadny_soubor chybovy vystupni stav = 2 mv: cannot access zadny_soubor chybovy vystupni stav = 2 cray105% ksh -e err5 cp cannot access zadny_soubor chybovy vystupni stav = 2 cray106% 13. Co ma Korn shell navic oproti Bourne shellu Behem vykladu v minulych kapitolach jsme obcas narazili na pro- stredek, ktery neslo zahrnout pod velmi casto se opakujici hlavicku "Bourne/Korn shell", protoze se nachazel pouze v Korn shellu. V teto kapitole "mnozinu ksh\sh", ktera vam ma pomoci udelat si o Korn shellu presnejsi predstavu a zvlaste jej doporucit pro vytvareni shellovskych scenaru, zhruba vymezime ve strucnem prehledu. Podrobnosti o jednotli- vych prostredcich i s ilustracnimi priklady v bohatem rozsahu nalezne- te v manualu [5]. Promenne . V Korn shellu neni nastaven zadny limit ohranicujici mnozstvi dat, ulozenych v promenne. (Jedinym omezenim je mnozstvi pameti dostupne pres funkci malloc procesu definujicimu promennou.) . Krome jednoduchych promennych je v Korn shellu take mozne pra- covat s jednodimenzionalnim polem do delky 1024 prvku, ktere se indexuji od 0 do 1023. Pro nastaveni hodnoty prvku pole pouzijte syntaxi pole[index]=hodnota Ke zpristupneni hodnoty prvku pole slouzi syntaxe ${pole[index]} Priklad: $ A[1]=prvek1 $ echo ${A[1]} prvek1 . V Korn shellu je mozne priradit promenne jeden nebo vice atri- butu, cimz lze ridit vnitrni reprezentaci dat v promenne, zpu- sob jejiho zobrazeni a jeji rozsah. Pro prirazeni atributu slouzi v Korn shellu vestaveny povel typeset s touto syntaxi: typeset [volby] [promenna] Povel typeset bez parametru vypise jmena a atributy vsech ak- tualnich promennych. Povel typeset s jednou nebo vice volbami, avsak bez promenne, vypise jmena vsech promennych s jejich hodnotami, ktere maji atribut(-y) nastaveny(-e) uvedenou(-ymi) volbou(-ami). V nasledujicim prikladu nektere z techto voleb demonstrujeme. Volba -u (uppercase) zabezpecuje prevod malych pismen v hodnote promenne na velka, volba -Rn (right-justified) zajisti pravy vyrez z hodnoty promenne v delce n znaku a volba -LZn (left- justified, strips leading zeros) zajisti levy vyrez z hodnoty promenne v delce n znaku, do nehoz se nezapocitavaji pripadne nevyznamne nuly zleva. Priklad: $ typeset -u Velkapismena $ Velkapismena=Abcde $ echo $Velkapismena ABCDE $ typeset .... uppercase Velkapismena .... $ typeset -u .... Velkapismena=ABCDE .... $ typeset -R4 Pravyvyrez $ Pravyvyrez=123456789 $ echo $Pravyvyrez 6789 $ typeset -LZ5 Levyvyrezbez0 $ Levyvyrezbez0=00027461232 $ echo $Levyvyrezbez0 27461 . V Korn shellu muzete urcit velikost hodnoty promenne (ve zna- cich) pomoci konstrukce ${#promenna} Priklad : $ Prom1=abcdefg $ echo ${#Prom1} 7 . V Korn shellu lze take ziskavat prave, resp. leve podretezce z hodnoty promennych odstranenim zadanych vzoru. Konstrukci ${promenna#vzor} ziskate hodnotu promenne, z niz byl z leve strany odstranen nejkratsi retezec znaku, ktery vyhovuje vzoru. Konstrukci ${promenna##vzor} ziskate hodnotu promenne, z niz byl z leve strany odstranen nejdelsi retezec znaku, ktery vyhovuje vzoru. Konstrukce ${promenna%vzor} a ${promenna%%vzor} jsou prave kolegyne dvou vyse uvedenych. Priklad: Ve vzorech se casto pouzivaji metaznaky. Nasledujici povely odstrani z leve strany hodnoty promenne Prom2 nejkratsi (resp. nejdelsi) retezec koncici pismenem A. $ Prom2=AAbbAbCCC $ echo ${Prom2#*A} AbbAbCCC $ echo ${Prom2##*A} bCCC $ . K promennym prostredi z Bourne shellu bylo v Korn shellu prida- no mnoho novych. (S jednou z nich, PS3, jste se setkali v odst. 11.3.) S jejich uplnym vyctem a vyznamem se muzete seznamit v manulalu [4]. Povelova substituce O konstrukci $(druhotna_povelova_radka) kterou jsme zminili v odst.2.2.2, lze zhruba rici, ze neinterpretuje "tolik urovni metaznaku" jako konstrukce `druhotna_povelova_radka` v Bourne shellu. Priklady tohoto jsou uvedeny v manualu [5]. Vlnovkova (tilda) substituce a alternativni povely (aliasy) Tyto substituce byly probrany v odstavcich 2.2 a 2.2.4. Ulozeni a zpristupneni predchozich povelu Mechanismus historie (history mechanism) v Korn shellu zavisi na nastaveni nekterych promennych prostredi. Toto nastaveni si zajistete ve vasem souboru .profile: u---------------i----------------------------------------------------o p Promenna p Vyznam a nastaveni hodnoty p u---------------i----------------------------------------------------o p EDITOR p Specifikuje editor pouzity pro editaci povelovych p p p radek. Jeji hodnotou muze byt /usr/bin/vi, p p p /usr/bin/emacs nebo /bin/ed. p p HISTFILE p Specifikuje cestu k souboru, kde budou vase pove- p p p love radky zapamatovany. Jeji hodnotou muze byt p p p napr. p p p $HOME/.ksh_history p p HISTSIZE p Specifikuje pocet povelovych radek, ktere si ma p p p Korn shell zapamatovat. Jeji primerenou hodnotou p p p je 100. p m--------------------------------------------------------------------. Jednim ze standardnich editoru v UNICOSu je vi, ktery je zrejme i edi- torem nejpouzivanejsim, a proto nadale predpokladejme nastaveni hodno- ty promenne EDITOR na /usr/bin/vi. Nejrychlejsi a nejjednodussi cestou, jak mechanismus historie v Korn shellu zpristupnit, je stisknout klavesy a , cimz se do- stanete do modu editace povelove radky a za promptem Korn shellu se objevi posledni povelova radka, kterou jste shellu zadali. Ocitnete se ve "zkracene" verzi editoru, ktery jste specifikovali promennou EDITOR; v nasem pripade je jim vi. Tato zkracena verze editoru obsahu- je vetsinu povelu s pusobnosti na jednu radku, ale neobsahuje zadne povely s pusobnosti na vice radek (krome presunu povelovych radek). Priklad: Predpokladejme, ze mame pro demonstraci mechanismu hi- storie v Korn shellu promennou PS1 nastavenou na hodnotu "! cray$ " (misto dosavadniho "$"); na zacatku kazde nabidky promptu bude vzdy uvedeno aktualni cislo povelu. Zahrnuti cisla povelu do promptu vam usnadni identifikaci povelove radky, ke ktere se chcete vratit. 1 cray$ echo $EDITOR /usr/bin/vi 2 cray$ date Mon Feb 13 14:26:37 MEZ 1995 3 cray$ ls -CF retezec_t retezec_t* 4 cray$ grep '[0-9]' retezec_t case [0-9]*: case *[0-9]: echo "Retezec sestava ze 3 malych pismen." 5 cray$ Stisknete klavesy a . 5 cray$ grep'[0-9]' retezec_t Vlozte nyni <5>, abyste dostali kurzor na pocatek retezce '[0-9]', a potom vlozte <7>, abyste retezec '[0-9]' zrusili. (Zname povely vi: l - posun kurzoru o jednicku doprava; x - zruseni jednoho znaku na aktualni pozici kurzoru.) 5 cray$ grep retezec_t Vlozte malych, abyste vlozili slovo "malych" (i - vkladani textu vlevo od kurzoru. 5 cray$ grep malych retezec_t Stisknete a dostanete nasledujici odpoved: echo "Retezec sestava ze 3 malych pismen." 6 cray$ Stisknete klavesy , <4> a . 6 cray$ date Dostali jste se o ctyri povelove radky nazpet, tedy k povelu date (6-4=2), (k - posun kurzoru o radku nahoru). Nyni se muzete stiskem klavesy <$> dostat na posledni znak radky (viz povel $ - pro posun kurzoru) a po stisku pri- psat parametry povelu date (a - vkladani textu vpravo od kurzoru). 6 cray$ date +%H%M%S Nyni stisknete : 144659 7 cray$ Rizeni procesu na pozadi Tento prostredek byl probran v odst.2.7. Logicke vyrazy a jejich vyhodnocovani V odst.10.2 jsme vysvetlili vyznam povelu test. V Korn shellu mu- ze tento povel vyhodnocovat celou radu podminek, ktere v Bourne shellu dostupne nejsou, napr. [ -l soubor ] pravda, jestlize soubor existuje a je to symbolicky link [ soubor1 -nt soubor2 ] pravda, jestlize soubor1 je mladsi nez soubor2 Krome toho poskytuje Korn shell i dalsi vyhodnocovac podminek, [[]], ktery se od povelu test lisi napr. tim, ze objekty zadane k vy- hodnocovani chrani pred substituci generovani jmen souboru aj. Aritmetika Pro vyhodnocovani aritmetickych vyrazu je v Korn shellu vhodny povel let. Korn shell provadi veskerou aritmetiku za pouziti nejdelsiho celociselneho typu dostupneho na systemu a nekontroluje preteceni. Nejvetsim kladnym celym cislem v Korn shellu je na Crayi 2^63-1. Povel let ma dva ekvivalentni formaty: let vyraz (( vyraz )) Priklad: Scenar 2na pocita mocninu cisla 2 pri zadanem exponentu: $ cat 2na #! /bin/ksh # syntaxe: 2na exponent # 2na: pocita 2^exponent vysledek=1 let exponent=$1+1 # kvuli prvnimu snizeni o 1 while(( (exponent=exponent -1) > 0 )) do let vysledek=2*vysledek done echo "2^$1 = $vysledek" $ 2na 62 2^62 = 4611686018427387904 $ Konstrukce select pro programovani menu Konstrukce select byla vysvetlena v odst.11.3. 14. Literatura K literature odkazovane v prirucce bychom chteli jeste pripojit poznamku o [3]. Jedna se o rozsahem malou publikaci, ve ktere vsak mu- ze ten, kdo se jiz o shellech alespon neco dozvedel, najit velmi rych- le syntaxi hledaneho prostredku shellu se strucnym vysvetlenim jeho semantiky. Publikace je vsak venovana pouze Bourne a C shellu. [1] C-6: Operacni system UNICOS (A. Cejchan, SAVT 1993) [2] C-9: Sluzby UNICOSu (A. Cejchan, SAVT 1995) [3] UNICOS Shell and Variable (Ready Reference) (SQ-2060) [4] UNICOS User Commands (Reference Manual) (SR-2011) [5] UNICOS Primer (SG-2010) [6] C-4: Pocitac Cray Y-MP EL ve FzU (M.Kratky, V.Kriz a I.Veltrusky, SAVT 1994) [7] UNICOS Support Tools Guide (SG-2016)