Obsah Varianty shellu.................................................................................................................................2 Základní pojmy ...............................................................................................................................2 Jednoduché příkazy..........................................................................................................................3 Návratové kódy................................................................................................................................3 Standardní vstupy a výstupy............................................................................................................3 Prázdný soubor.................................................................................................................................3 Kolony .............................................................................................................................................3 Seznamy...........................................................................................................................................4 AND (&&) / OR (||).....................................................................................................................5 Závorkování.....................................................................................................................................6 Zrušení řídícího významu speciálních znaků...................................................................................7 Obrácené lomítko ( \ )..................................................................................................................7 Apostrofy ( ` )...............................................................................................................................8 Uvozovky ( “ “ )...........................................................................................................................8 Expanze............................................................................................................................................8 Expanze jmen (*-expanze)...........................................................................................................8 Expanze pomocí složených závorek............................................................................................9 Skripty..............................................................................................................................................9 Obsah skriptu..............................................................................................................................10 Proměnné.......................................................................................................................................10 Parametry.......................................................................................................................................11
UNIX – Uživatelské rozhraní Shell je interpret programovacího jazyka. Čte příkazy z terminálu a provádí je. Jeho nejznámější varianta je tzv. Bourne shell, známý pod názvem sh. Známe ještě další varianty jako je ku příkladu GNU Bourneagain shell bash.
Varianty shellu Uživateli se po přihlášení spustí ten shell (terminál), který je nastaven v jeho uživatelském záznamu v souboru /etc/passwd. Shell, který se použije jako první, se nazývá login shell a má výsadní postavení. Rozlišujeme interaktivní a neinteraktivní shell. Interaktivní shell má vstup a výstup napojen na terminál. Neinteraktivní je ten, který spouštíme aby četl skript ze souboru. Interaktivní shell jiného než login shell hledá v domovském adresáři konfigurační soubor .bashrc a pokud ho najde, tak ho spustí.
Základní pojmy Definujme si následující základní pojmy: Bílé místo Je alespoň jednoznaková posloupnost mezer a tabulátorů. Slovo Je posloupnost znaků, která se v shellu považuje za samostatnou, dále nedělitelnou jednotku. Jméno Je slovo tvořené písmeny, číslicemi a znakem podtržení _. Jméno začíná buď písmenem nebo znakem _. Taktéž se nazývá identifikátorem. Metaznak Je znak kterým se oddělují slova. Je to jeden z těchto znaků: | & ; ( ) < > mezera tabulator Řídící operátor Je slovo které vyvolá určitou řídící operaci. Jde o tato slova: | || & && ; ;; ( ) nový řádek Rezervovaná slova Jsou to slova, která mají v shellu zvláštní význam. Jde o tato slova: ! case do done elif else esac fi for function until while { }
if
in
select
then
Jednoduché příkazy Jednoduchý příkaz je posloupnost slov oddělených bílím místem. První slovo určuje příkaz, který se provede. Ostatní slova se příkazu přiřadí jako argumenty (parametry).
Příklad jednoduchého příkazu: cd adresar
Návratové kódy Každý spuštěný binární program v systému UNIX po ukončení vrací návratový kód. Návratový kód je celé kladné číslo a hodnota 0 znamená, že vše proběhlo v pořádku. Hodnota, která není 0 znamená, že během vykonávání programu nastala chyba.
Standardní vstupy a výstupy Každý program (proces) v UNIX-u má alespoň dva výstupy. První je standardní výstup a druhý je standardní chybový výstup. Tyto výstupy je možno přesměrovat. A to za pomoci znaku „>” nebo znaků „2>”. Tento znak/-y stačí uvést za poslední argument příkazu. Příkaz ls > ./soubor.txt vypíše obsah aktuálního adresáře do souboru „soubor.txt“, který bude uložen aktuálním adresáři. Chybový výstup však bude vypsán na obrazovku. Příkaz ls adr 2> ./err.txt vypíše na obrazovku obsah adresáře adr a do souboru err.txt vypíše chybový výstup (například kdyby neexistoval adresář adr). Standardní výstup je také možno přesměrovat za pomoci operátoru >>. V tomto případe však nedochází k přepsání souboru jako u operátoru > a data jsou zapisována na konec souboru.
Prázdný soubor V systému UNIX existuje soubor /dev/null, který reprezentuje zařízení, které je prázdné. Je možno si ho představit jako obdobu „koše“ ze systému Microsoft Windows. Z tohoto zařízení se však nedají žádné soubory obnovit. Příkaz ls adr 2> /dev/null vypíše chybovou hlášku (pokud například adresář adr neexistuje) do prázdného zařízení a není vidět na výstupu na display.
Kolony Kolona je posloupnost jednoho nebo více příkazů oddělených metaznakem |. Formát zápisu je následovný: [!] příkaz1 [| příkaz2] Význam kolony je následující. Výstup z příkaz1 se použije pro vstup pro příkaz2. Je nutno si uvědomit, že všechny příkazy v koloně jsou spuštěny najednou a ukončují jse až když dostanou na vstup EOF což je speciální znak End Of File. Znak ! představuje negaci návratového kódu. Negace znamená obyčejně obrácená hodnota. Negace návratového kódu 1 a více je 0 a negace návratového kódu 0 je 1.
Příklad: Příkaz ls jako takový vypisuje obsah adresáře. Příkaz more čte vstup a formátuje ho na oddělené řádky. Kolona ls | more pracuje tak, že výpis příkazu ls naformátuje na samostatné řádky.
Příklad 2: Příkaz grep vyhledává v daném vstupu řetězec a řádek vstupu na kterém je nalezen tento řetězec vypisuje na standardní výstup. Kolona ls –lR | grep “jmenosouboru” vytvoří v paměti procesy pro příkaz ls a příkaz grep příkaz ls s parametry –l (podrobný výpis) –R (rekurzivně na všechny podadresáře) začne vypisovat obsah daného adresáře a všech podadresářů na svůj standardní výstup. Tento výstup je přesměrován na vstup pro příkaz grep, který postupně prochází vstup a hledá v něm posloupnost znaků „jmenosouboru“. Jakmile najde takovouto posloupnost znaků v nějakém řádku, tak celý řádek vypíše na výstup cože je standardně obrazovka displaye.
Seznamy Seznam je posloupnost jednoho nebo více kolon (příkazů) oddělených jedním z řídících operátorů ||
&
&&
;
A je ukončena jedním z následujících operátorů &
;
nový řádek
Pokud je příkaz ukončen operátorem &, shell jej provádí v kopii shellu na pozadí, nečeká se na dokončení příkazu. Pokud ale oddělíme příkaz za pomoci středníku ; tak bude shell vykonávat příkazy sekvenčně.
Příklad: cd dir1&ls Spustí se zároveň příkaz cd a zároveň příkaz ls. Výsledek je takový, že příkaz cd se spustí na pozadí a v kopii shellu se změní adresář a potom se tato kopie shellu ukončí. Zatím se spustí příkaz ls a ten na obrazovku vypíše obsah právě prohlíženého adresáře. cd dir;ls Spustí se nejdříve příkaz cd, který změní pracovní adresář a po jeho dokončení se spustí příkaz ls, který vypíše na obrazovku obsah pracovního adresáře.
A
B
A AND B
A OR B
1+
1+
1
1
1+
0
1
0
0
1+
1
0
0
0
0
0
AND (&&) / OR (||)
V praxi se často používají operace AND a OR. Pro přehlednost je zde vidět tabulka fungování AND a OR. V tabulce znamená hodnota 1+, že příkaz skončil s chybou a hodnota 0 že příkaz proběhl správně. Pokud kupříkladu skončil program A z chybou a program B také z chybou tak výsledná návratová hodnota operace AND bude 1 a operace OR také 0. Operace AND je reprezentována v systému UNIX operátorem && a operace OR je reprezentována operátorem ||. Systém UNIX se snaží získat hodnotu návratového kódu co nejdříve a tímto způsobem také vyhodnocuje jestli bude další příkaz v seznamu vyhodnocen.
Příklad: Pokud budeme mít seznam OR (||) a zápis bude následovný: příkaz1 || příkaz2. Z tabulky je vidět, že pokud se příkaz1 ukončí s návratovým kódem 0 tak už nezáleží na tom jakým návratovým kódem by skončil příkaz2. Návratová hodnota seznamu bude pořád 0 bez ohledu na návratový kód příkazy2. Proto systém UNIX ani nespustí příkaz2 a vrátí návratovou hodnotu 0. Pokud by příkaz1 vrátil návratovou hodnotu 1 a více tak systém UNIX musí zjistit ještě hodnotu příkazu2 aby věděl vrátit celkový návratový kód seznamu a proto jakmile získá návratový kód příkazu1 spustí příkaz2 a počká na jeho dokončení a potom vrátí celkový návratový kód.
Příklad2: Pokud budeme mít seznam AND (&&) a zápis seznamu bude následovný: příkaz1 && příkaz Opět je vidět z tabulky, že pokud příkaz1 skončí s návratovou hodnotou 1 tak je možné bez znalosti návratového kódu příkazu2 vrátit hodnotu 1. Systém UNIX šetří výpočtový čas a nespustí ani příkaz2 a vrátí hodnotu 1. Naopak pokud by skončil příkaz1 s návratovou hodnotou 0 tak bez znalosti návratového kódu příkazu2 není možné vrátit celkovou návratovou hodnotu seznamu a proto UNIX jakmile se dokončí příkaz1 spustí příkaz2 a po jeho dokončení vrátí spočtenou hodnotu jako návratový kód seznamu.
Jednoduchá poučka: Při použití OR se nevykonávají další příkazy první příkaz byl proveden bez chyb. Při použití AND se nevykonají další příkazy pokud první příkaz skončil s chybami.
Závorkování Seznam příkazů můžete uzavírat do závorek. Jsou dvě možnosti. (seznam) Tímto způsobem uzavřený seznam se vykoná v kopii shellu. Jakékoliv změny, či proměnné nastavené během tohoto nového shellu se ztrácejí. Jediné, co je možno získat je návratová hodnota seznamu uzavřeného v závorkách. { seznam;} Tímto způsobem uzavřený seznam se vykoná v právě běžícím shellu ze kterého je tento příkaz spuštěn. Návratovým kódem je návratový kód seznamu. Pozor na nezbytnost bílého místa po první závorce a středníku před poslední závorkou.
Příklad: cd adresar || { mkdir adresar; cd adresar;} Jako první se vykoná příkaz cd adresar. Na základe jeho návratové hodnoty (operace OR) se UNIX rozhodne jestli vykonávat seznam a získat jeho návratovou hodnotu. Pokud proběhne cd adresar v pořádku, tak se seznam nevykoná. Pokud proběhne s chybou tak se vykoná seznam { mkdir adresar; cd adresar;}. Příkaz mkdir adresar se pokusí vytvořit adresar. Bez ohledu na to jestli se mu to podaří se až po jeho ukončení (díky středníku ;) spustí příkaz cd adresar. Návratová hodnota seznamu je zde jeho poslední příkaz. Je tak protože se nejedná o OR nebo AND operátory uvnitř seznamu. Návratová hodnota seznamu v závorkách je návratová hodnota příkazu cd adresar. Návratová hodnota celého příkazu je návratová hodnota podle tabulky OR. Viz tabulka.
Osvětlení tabulky: Pokud proběhne příkaz cd adresar s chybou tak se vykoná seznam. V seznamu se vykoná mkdir adresar a po něm se vykoná cd adresar. V našem případě se vykonal poslední cd adresář v pořádku (řádek s červeným písmem) a návratová hodnota seznamu je 0 a podle OR, 1+ || 0 je 0. Celková návratová hodnota je 0.
A
A OR B
cd adresar
B=C;D B=C;D
C
D
mkdir adresar
cd adresar
1+
1+
1+
1+
1+
1+
0
0
1+
0
1+
1+
1+
0
1+
1+
0
0
0
0
0
0
1+
1+
1+
0
0
0
1+
0
0
0
1+
0
1+
0
0
0
0
0
Příklad2 (zkuste si doma sami): Porovnejte si sami v čem se liší tyto dva příkazy: (pwd; cd adresar; pwd);pwd { pwd; cd adresar;pwd;};pwd
Zrušení řídícího významu speciálních znaků Vzhledem k tomu, že někdy potřebujeme zadat speciální znak v shellu a potřebujeme aby byl chápán jako samostatný znak a ne jako řídící operátor, tak je nutné jeho řídící funkci potlačit. Takovýto případ je když potřebujeme vytvořit soubor s názvem JA&TY.txt. Pokud by jsme napsali touch JA&TY.txt tak by shell vykonal seznam příkazů JA (který neexistuje) a bez počkání na dokončení tohoto příkazu (díky operátoru &) by spustil příkaz TY.txt (který také neexistuje). Na potlačení řídícího významů operátorů se používají tři způsoby.
Obrácené lomítko ( \ )
Obrácené lomítko \ se používá velice často. Jakýkoliv znak který je za obráceným lomítkem ztrácí svůj řídící význam. Lomítko ovlivňuje jenom znak bezprostředně za lomítkem. Speciální znak je je bílé místo. Sami si zkuste příkazy a zjistěte jak je důležité zakazovat řídící funkce operátorů: touch touch touch touch mkdir mkdir
a b a\ b ja&ty.txt ja\&ty.txt ||ps&&ls \|\|ps\&\&ls
Apostrofy ( ` ) Uzavřením do apostrofů ztrácejí svůj řídící význam všechny řídící znaky kromě apostrofů. Ten do apostrofů uzavřít nelze. Zkuste si: touch ahoj&ps touch `ahoj&ps`
Uvozovky ( “ “ )
Uzavřením znaků do dvojice uvozovek ztrácí řídící znaky svůj význam. Výjimkou jsou tyto znaky: $ ‘ \ Příklady: Zkuste si funkcionalitu následujících příkazů: echo \’ echo ‘\’ echo \\ echo “’” echo “\’”
Expanze Expanze jmen (*-expanze)
V prostředí UNIX je expanze za pomoci znaků *,? a […] je poměrně častá záležitost a bez této funkcionality by bylo se systémem velice obtížné pracovat. Ku příkladu pokud chcete odstranit veškeré soubory které se nachází ve složce není nic lehčího než napsat příkaz rm s parametrem *. Celková expanze funguje tak, že nejdříve se vytvoří seznam všech odkazů v adresáři a tento seznam se pak filtruje za pomoci operátorů * a ?.
Záměna * Hviezda (*) představuje jakýkoliv množství znaků, které po sobě jdou. Jedinou výjimkou jsou soubory, které začínají znakem tečka (.), soubory jako třeba .passwd, či .shadow nejsou operátorem * akceptovány.
Záměna ? Otazník (?) předstauje právě jeden a to jakýkoliv znak.
Příklady pozitivně či negativně vyhodnocené expanze: Mějme adresář ve kterém jsou umístěny soubory a spouštíme příkaz ls s parametry –lad postupně s dalším parametrem (*; *.*; .*; ?.txt; *.txt; ahoj?.*; .*.????; 9?.*)
Název souboru
*
*.*
.*
?.txt
*.txt
ahoj?.*
.*.????
9?.*
ahoj1.txt
ANO
ANO
NE
NE
ANO
ANO
NE
NE
l.txt
ANO
ANO
NE
ANO
ANO
NE
NE
NE
.shadow
NE
NE
ANO
NE
NE
NE
NE
NE
.smile.face
NE
NE
ANO
NE
NE
NE
ANO
NE
92.pass
ANO
ANO
NE
NE
NE
NE
NE
ANO
83.pass
ANO
ANO
NE
NE
NE
NE
NE
NE
ahoj
ANO
NE
NE
NE
NE
NE
NE
NE
Expanze pomocí složených závorek Pro urychlení práce při operacích v příkazovém řádku je možné použit expanze za pomoci seznamů. Seznam slov pro nahrazení je vždy uzavřen ve složených závorkách { } a slova uvnitř jsou oddělena za pomoci symbolu čárky ( , ). Uveďme příklad: mkdir /usr/local/src/typo/{bad,good,lame,top,bottom} Je po expanzi převeden na sérii příkazů: mkdir mkdir mkdir mkdir mkdir
/usr/local/src/typo/bad /usr/local/src/typo/good /usr/local/src/typo/lame /usr/local/src/typo/top /usr/local/src/typo/bottom
Tímto způsobem je možné napsat jenom jeden řádek místo více.
Skripty
Skript si můžeme představit jako zápis programu který bude vykonávat shell. Jde o sérii příkazů, které jsou interpretovánu stejně jako by bylo v terminálovém okně. Hned na začátku je důležité upomenout, že skript na rozdíl od binárního programu nemůže mít rozdílné GID a UID. Skripty mohou být prováděné jenom s právy na čtení, read (r) a to za pomoci příkazu bash nebo za pomoci . . Pokud by se skript jmenoval skript12 tak by zápis příkazu pro spuštění ve vnořeném shellu následovný: bash skript12 . skript12 Pokud budeme chtít, aby skript byl spouštěn i správy na čtení a spuštění (r,x) tak bude spouštěn buď za pomoci pouhého napsání jeho jména (v případe že je v systémových cestách zapsána adresářová struktura kde se nachází daný skript) nebo za pomoci uvedení cesty k souboru skriptu. Ku příkladu:
skript12 ./skript12
Obsah skriptu
Na začátku skriptu musí být vždy napsáno jaký interpret se má spustit. Toto je zaručeno a nastaveno za pomoci prvního řádku souboru, kde by se měla nacházet dvojice znaků #! a za ní cesta k danému interpretu (shellu). Jakékoliv další řádky shellu jsou jenom zápisy spustitelných souboru a dalších shellu jako v příkazové řádce. Ukázka shellu, který vypisuje na standardní výstup (běžně obrazovka terminálu) text „Ahoj to jsem ja“.
#!/bin/bash echo Ahoj to jsem ja
Proměnné Systém UNIX dovoluje zapisovat proměnné, jako v programovacích jazycích. Proměnné v systému UNIX jsou však čistě textové. Pro přiřazení proměnné danou hodnotu je používán zápis.
jméno_proměnné = [hodnota] Danou proměnnou můžeme potom libovolně používat během daného shellu a to tak, že před jméno proměnné napíšeme symbol $.
$jméno_proměnné Příklad: TEMPADRESAR = /dev/boot/temp ls $TEMPADRESAR mkdir $TEMADRESAR/projekt1 Tato série příkazů vytvoří proměnnou TEMPADRESAR která je potom použita na výpis příkazu ls v adresáři /dev/boot/temp a nakonec pro vytvoření adresáře projekt1 v adresáři /dev/boot/temp. Výpis všech aktuálně nastavených proměnných je možné vypsat za pomoci příkazu printenv.
Parametry Vzhledem k tomu, že téměř všechny příkazy v systému UNIX používají parametry tak i skripty jsou schopny tyto parametry načítat a je možno skripty pouštět s parametry. Všechny parametry jsou do skriptu automaticky uloženy jako lokální proměnné a mají názvy 1, 2, 3, 4, ... . Pokud chci například vypsat na standardní výstup text Opacne: a pak nejdříve druhý parametr a potom první parametr, tak bude skript vypadat následovně:
#!/bin/bash echo Opacne: $2 $1 Pokud spustíme skript který je zde napsán následovně:
skript Smile Camera Tak bude výstup vypadat takto:
Opacne: Camera Smile