Zpracování příkazové řádky shellem Shell je interpret příkazů programovacího jazyka. Zpracovává příkazy nebo přiřazení hodnot poměnným. Vstupem shellu může být soubor nebo standardní vstup. Je-li shell vyvolán se jménem začínajícím - (minus), jedná se o tzv. login shell login shell načítá při startu inicializační soubory: sh, ksh - /etc/profile a $HOME/.profile csh - $HOME/.login shelly s výjimkou sh načítají při každém spuštění další inicializační soubor: ksh - $ENV csh - $HOME/.cshrc predn_02.doc 18.11.01 23:13 1
Základní pojmy Metaznaky ;, &, (, ),, <, >, LF, mezera, tabulátor Identifikátor posloupnost tvořená písmeny, podtržítky a číslicemi nezačínající číslicí malá a velká písmena se rozlišují Oddělovač parametrů mezera nebo tabulátor Pojmenovaný parametr (proměnná) identifikátor Parametr proměnná dekadické číslo některý ze znaků:!, #, $, *, -,?, @, _ predn_02.doc 18.11.01 23:13 2
Přiřazení hodnoty proměnné proměnná=hodnota proměnná je identifikátor - název proměnné. Mezi ním a = nesmí být mezera. hodnota je přiřazovaná hodnota (textový řetězec) Před přiřazením hodnoty proběhnou na řádce náhrady stejně jako u příkazů (viz dále) $proměnná náhrada proměnné hodnotou Příklad: $ echo $aaa $ aaa=1 $ echo $aaa 1 $ predn_02.doc 18.11.01 23:13 3
Příkaz Posloupnost slov a metaznaků podle synaxe shellu. Shell příkazy čte a provádí samostatně nebo vyvoláním samostatných programů. Příkaz dědí od shellu (rodičovského procesu) kromě jiného: prostředí (enviroment) otevřené soubory (vždy vstup, výstup a chybový výstup) Příkaz vrací návratový kód (0 = úspěšné provedení, <>0 = chyba) Příkaz může volat další příkazy. Shell je také příkaz Příkaz může být jednoduchý nebo složený. Příkazy mohou být seskupovány do kolon a seznamů příkazů predn_02.doc 18.11.01 23:13 4
Jednoduchý příkaz Posloupnost slov oddělených mezerami nebo tabulátory zakončená metaznakem. První slovo je jméno příkazu, zbývající slova jsou argumenty příkazu. Jednoduchý příkaz může být: zabudovaný příkaz - prováděn shellem bez vytvoření nového procesu dávka příkazů (skript) - prováděn novým shellem externí program - prováděn jako nový proces Složené příkazy (Compound Commands) case, for, function, if, time, until, while, ( ), { } - budou probrány později Příklady: $ cd $ pwd /home/honza predn_02.doc 18.11.01 23:13 5
Kolona příkazů (Pipeline) Posloupnost jednoho nebo více příkazů oddělených znakem. Standardní výstup předchozího je standardním vstupem následujícího příkazu. Návratový kód kolony je návratový kód posledního příkazu. Příkazy v koloně se startují odzadu a běží paralelně. V kolonách se často volají tzv. filtry (standardní programy zpracovávající text). Některé často používané filtry: cat, split, head, tail, more, cut, paste, sort, uniq wc, tr, tee grep, sed, awk Příklad: $ ps -ef grep grep honza 553 489 0 16:23:19 pts/2 0:00 grep grep predn_02.doc 18.11.01 23:13 6
Seznam příkazů (List) Posloupnost jedné nebo více kolon oddělených znaky: ; (středník) nebo LF (nová řádka) - sekvenční provádění příkazů (nejprve se provedou příkazy před a pak příkazy za středníkem (novou řádkou) & - asynchronní provedení předchozí kolony (shell nečeká na její dokončení - provádění "na pozadí") && - sekvenční provádění. Kolona "za" se provede pouze tehdy, vrátí-li kolona "před" nulový návratový kód (skončí bez chyby). - sekvenční provádění. Kolona "za" se provede pouze tehdy, vrátí-li kolona "před" nenulový návratový kód (skončí s chybou). predn_02.doc 18.11.01 23:13 7
Příklady: $ pwd; cd..; pwd; cd; pwd /home/honza /home /home/honza $ $ ps -f UID PID PPID C STIME TTY TIME CMD honza 345 341 0 20:45:17 pts/2 0:00 -ksh $ sleep 100& [1] 365 $ ps -f UID PID PPID C STIME TTY TIME CMD honza 345 341 0 20:45:17 pts/2 0:00 -ksh honza 365 345 0 21:17:05 pts/2 0:00 sleep 100 $ $ ls; [ -f t1 ] && touch t2; [ -f t1 ] touch t3; ls konec t1 testik text vypis konec t1 t2 testik text vypis $ predn_02.doc 18.11.01 23:13 8
Rušení významu speciálních znaků (Quoting) Speciální význam znaků v shellu lze zrušit následovně: \ (obrácené lomítko) ruší speciální význam následujícího znaku '...' všechny znaky uzavřené mezi apostrofy ztrácejí speciální význam (kromě apostrofu) "..." mezi uvozovkami ztrácí speciální význam všechny znaky kromě: \ (obráceného lomítka) - rušení spec. významu následujícího znaku `...` (obrácené apostrofy) - náhrada příkazů $ (dollaru) - náhrada parametrů Při interpretaci řádky shell tyto znaky odstraní. predn_02.doc 18.11.01 23:13 9
Příklady: $ echo * konec testik text vypis $ echo \* * $ echo '*' * $ echo "\$HOME je $HOME" $HOME je /home/honza $ echo "Obracene lominto na konci radky \ > dela pokracovaci radku" Obracene lominto na konci radky dela pokracovaci radku $ predn_02.doc 18.11.01 23:13 10
Náhrady na příkazové řádce shell načítá příkazy a provádí je před provedením provede následující náhrady (úpravy): Vynechání komentářů část řádky za znakem # (včetně tohoto znaku) se chápe jako komentář a je ignorována Náhrada alias (Aliassing) - ne sh první slovo příkazu je porovnáno se seznamem "aliasů" a pokud je nalezeno, je nahrazeno odpovídající pravou stranou "aliasu" končí-li pravá strana "aliasu" mezerou nebo tabulátorem, testuje se i druhé slovo náhrada se provádí při načítání příkazu, ne při jeho provádění shell má předdefinováno cca 10 "aliasů" predn_02.doc 18.11.01 23:13 11
Příklad $ # toto je komentar $ alias #bez parametru vypise nadefinovane aliasy autoload='typeset -fu' command='command ' functions='typeset -f' history='fc -l' integer='typeset -i' local=typeset nohup='nohup ' r='fc -e -' stop='kill -STOP' suspend='kill -STOP $$' $ # 2. slovo prikazu zacinajiciho nohup bude testovano na alias $ alias m=more # takto se nadefinuje novy alias $ ls m # takto se pouzije... predn_02.doc 18.11.01 23:13 12
Náhrada ~ (Tilde Substitution) - ne sh samotný znak ~ (případně následovaný znakem /) - je nahrazen domovským adresářem uživatele ~jméno_uživatele - je nahrazeno domovským adresářem tohoto uživatele v ostatních případech (např. jméno neodpovídá žádnému uživateli) zůstává text nezměněn Příklad: $ pwd; ls; cd ~root; pwd; ls ~ /home/honza konec t1 t2 testik text vypis /root konec t1 t2 testik text vypis $ predn_02.doc 18.11.01 23:13 13
Náhrada příkazů (Command Substitution) Příkaz uvedený mezi opačnými apostrofy (`příkaz`) nebo v konstrukci $(příkaz) (ne v sh) je proveden a nahrazen (včetně těchto apostrofů resp. dollaru a závorek) svým standardním výstupem Příklad: $ pwd; cd `echo /etc`; pwd; cd /root /etc $ DATE=`date` $ echo `date` $DATE Sat Oct 6 21:37:54 MEST 2001 Sat Oct 6 21:37:20 MEST 2001 $ echo `date`: $DATE Sat Oct 6 21:38:18 MEST 2001: Sat Oct 6 21:37:20 MEST 2001 $ predn_02.doc 18.11.01 23:13 14
Náhrada parametrů a proměnných (Parameter Substitution) Konstrukce $parametr je nahrazena hodnotou tohoto parametru Parametrem může být: poziční parametr ($1) pojmenovaná proměnná ($HOME) speciální proměnná ($#) Tyto náhrady budou probrány podrobněji později Interpretace oddělovačů parametrů (Blank Interpretation) Řádka je pomocí oddělovačů parametrů rozdělena do jednotlivých parametrů. Oddělovač parametrů je standardně mezera nebo tabulátor, může být změněn nastavením proměnné IFS. Dva parametry mohou být odděleny libovolným počtem oddělovačů. Parametry jsou předány volanému příkazu. V shellu jsou pak přístupné jako $1, $2... predn_02.doc 18.11.01 23:13 15
Náhrada jmen souborů (File Name Generation) Náhrada slov příkazové řádky obsahujících znaky *,?, [, ]odpovídajícími jmény souborů. *: odpovídá libovolnému řetězci kromě tečky na začátku jména a / kdekoliv?: odpovídá jednomu libovolnému znaku kromě tečky na začátku jména a / kdekoliv [abc] resp [a-z]: odpovídá jednomu znaku z uvedených resp. z uvedeného intervalu [!abc] odpovídá jednomu znaku různému od uvedených Řádka po náhradě může být mnohem delší. Znaky. (tečka) na začátku jména a / se musí explicitně uvádět. Nahrazování lze potlačit příkazem set -f (nedoporučuje se) a opět povolit příkazem set +f. predn_02.doc 18.11.01 23:13 16
Příklady: $ echo * # vsechny soubory nezacinajici teckou a aa ab abc alfa beta $ echo.* # vsechny soubory zacinajici teckou....kshrc.profile.sh_history $ echo a* # soubory zacinajici znakem a a aa ab abc alfa $ echo a? # dvouznakove soubory zacinajici a aa ab $ echo *[AB]*# soubory obsahujici velke A nebo B aa ab abc $ echo [!a]* # soubory nezacinajici a beta $ echo *d* # soubory obsahujici d - nejsou *d* predn_02.doc 18.11.01 23:13 17
Přesměrování (Redirection) Programy přistupují k souborům pomocí tzv. deskriptorů. Deskriptor je malé celé číslo. Každý program má při spuštění standardně otevřeny tyto deskriptory: 0 - standardní vstup 1 - standardní výstup 2 - standardní výstup chyb Nový proces standardně dědí deskriptory od svého rodiče Před provedením příkazu toto shell mění v koloně nebo na základě následujících konstrukcí: <jméno_souboru soubor jméno_souboru bude otevřen a nastaven jako standardní vstup programu. > jméno_souboru soubor jméno_souboru bude otevřen jako standardní výstup programu pokud soubor neexistuje, bude vytvořen pokud existuje, bude přepsán (lze potlačit nastavením noclobber - ne v sh) predn_02.doc 18.11.01 23:13 18
>> jméno_souboru soubor jméno_souboru bude otevřen pro výstup a nastaven jako standardní výstup pokud soubor neexistuje, bude vytvořen pokud existuje, bude výstup připojen za konec souboru $ date>vypis; ls >>vypis $ cat vypis wc -l 3 $ cat xxx cat: cannot open xxx $ cat < xxx ksh: xxx: cannot open $ cat vypis Sun Mar 4 09:38:08 MET 2001 testik vypis $ cat < vypis Sun Mar 4 09:38:08 MET 2001 testik vypis $ predn_02.doc 18.11.01 23:13 19
<<slovo shell čte vstup až do řádky začínající slovem slovo nebo do konce souboru načtený text se stane standardním vstupem příkazu (tzv. here-dokument) v textu se provádí náhrada parametrů a příkazů (pokud není uvedeno \slovo) znakem \ lze v případě potřeby zrušit význam znaků $, `, \ a NL $ cat << konec > text > tento text je cten shellem a ukladan do souboru text > promenne jsou nahrazeny: $HOME > soubory ne: * > text musi byt zakoncen radkou zacinajici uvodnim slovem > konec $ cat text tento text je cten shellem a ukladan do souboru text promenne jsou nahrazeny: /home/honza soubory ne: * text musi byt zakoncen radkou zacinajici uvodnim slovem $ predn_02.doc 18.11.01 23:13 20
následující konstrukce kopírují (duplikují) deskriptor souboru duplikát lze použít místo původního souboru m>soubor přesměrování výstupu s deskriptorem m do souboru soubor m>>soubor připojení výstupu s deskriptorem m do souboru soubor <&n do deskriptoru 0 (standardní vstup) je přiřazen deskriptor n m<&n do vstupního deskriptoru m je přiřazen deskriptor n >&n do deskriptoru 1 (standardní výstup) je přiřazen deskriptor n m>&n do výstupního deskriptoru m je přiřazen deskriptor n predn_02.doc 18.11.01 23:13 21
při vícenásobném přesměrování se přesměrování vyhodnocují zleva doprava: 1>s1 2>&1 - přesměruje standardní výstup do souboru s1 a standardní výstup chyb do standardního výstupu (tedy s1) 2>&1 1>s1 - přesměruje standardní výstup chyb na standardní výstup (nejspíše terminál) a pak standardní výstup do souboru s1 příkazem exec a přesměrováním lze změnit přiřazení deskriptorů běžícího shellu predn_02.doc 18.11.01 23:13 22
Prostředí procesu (Enviroment) každý proces dostává od svého rodiče kopii tzv. prostředí jedná se o seznam proměnných s hodnotami prostředí lze vypsat příkazem env proměnnou lze zařadit do prostředí příkazem export potomek nemůže změnit prostředí rodiče p $ env PATH=/bin LOGNAME=honza PS1=$ SHELL=/bin/ksh HOME=/home/honza TERM=vt100 PWD=/home/honza TZ=MET ENV=/home/honza/.kshrc $ predn_02.doc 18.11.01 23:13 23
Provedení příkazu 1 čtení příkazu konec vstupu? + - substituce na příkazové řádce konec zabudovaný příkaz? + provedení příkazu - 1 predn_02.doc 18.11.01 23:13 24
rodič fork () potomek + příkaz na popředí? binární program? + wait (potomek) - - open(prikaz) exec (příkaz) 1 1 1 predn_02.doc 18.11.01 23:13 25
predn_02.doc 18.11.01 23:13 26