Menu

Standardní vstup, výstup a chybový výstup

Standardní vstup a výstup, resp. chybový výstup jsou vstupní a výstupní kanály, kterými proces komunikuje se svým prostředím (s shellem). Standardní vstup stdin je obvykle přijímán z klávesnice, standardní výstup stdout a standardní chybový výstup stderr jsou vypisovány na obrazovku. stderr slouží především pro výpis chybových hlášení.

Každý vstup, resp. výstup má přiřazeno číslo. Toto číslo souvisí se souborovým deskriptorem v jazyce C.

0 – stdin
1 – stdout
2 – stderr

Přesměrování standardního vstupu a výstupů nám umožňuje odpojit je od klávesnice a obrazovky a místo toho číst vstup, resp. vypisovat výstup jinam – do souboru, na standardní vstup jiného příkazu apod. Díky přesměrování spolu mohou jednotlivé programy komunikovat. Jedná se o naprosto zásadní techniku – jsou-li jednotlivé příkazy základními kameny, které tvoří budovu programování v shellu, pak přesměrování je maltou, která je drží pohromadě.

Přesměrování stdin

Standardní vstup lze načíst ze souboru místo z klávesnice:

příkaz < soubor
wc -l < /etc/passwd   ... vypíše počet řádek souboru /etc/passwd
wc -l 0< /etc/passwd  ... to samé, ale s explicitním zmíněním čísla deskriptoru
                          u stdin se v praxi téměř nepoužívá

Jaký je rozdíl mezi voláním wc -l < /etc/passwd a wc -l /etc/passwd? V druhém případě vypíše wc kromě počtu řádek i název souboru. V prvním případě ale data přišla na standardní vstup – wc neví o tom, že pochází ze souboru /etc/passwd a ani ho to nezajímá. Vypíše tedy pouze počet řádek.

Přesměrování stdout

Standardní výstup můžeme mimo jiné přesměrovat do souboru. Přesměrování do souboru má dvě varianty – podle toho, zda chceme cílový soubor přepsat, nebo jen připsat data na jeho konec. V každém případě, pokud přesměrováváme výstup do souboru, který ještě neexituje, bude automaticky vytvořen.

date > datum.txt   ... zapíše do souboru datum.txt aktuální datum a čas; původní obsah se přepíše
date >> datum.txt  ... připíše na konec souboru datum.txt aktuální datum a čas

Oba předchozí způsoby můžeme opět zapsat i s explicitním zmíněním čísla deskriptoru. Ani u standardního výstupu číslo deskriptoru obvykle neuvádíme, je však dobré si uvědomit, co se za > skutečně skrývá:

date 1> datum.txt
date 1>> datum.txt

Přesměrování stderr

Standardní chybový výstup můžeme stejně jako stdout přesměrovat do souboru a stejně jako v případě stdout se můžeme rozhodnout, zda soubor přepsat, či připisovat na jeho konec. V tomto případě však už skutečně musíme číslo deskriptoru uvést – žádný zkrácený zápis neexistuje.

ls /blabla 2> chyby.log
ls /blabla 2>> chyby.log

Výstup však nemusíme přesměrovat jenom do souboru. Někdy může být zajímavé přesměrovat stderr na stdout či naopak.

ls /bla > vystup.txt 2>&1   ... stderr je přesměrován na stdout a ten pak do souboru vystup.txt
ls /bla 2> error.txt 1>&2   ... stdout je přesměrován na stderr a ten pak do souboru error.txt

Roura

Roura je mechanismus, který vezme dva příkazy a přesměruje standardní výstup prvního z nich na standardní vstup druhého. Zapisuje se pomocí |.

ls -1 ~ | wc -l  ... spočítá počet souborů v domovském adresáři

Pokud chceme, můžeme rouru opsat pomocí obyčejných přesměrování a dočasného souboru. Ten pak ale po sobě musíme uklidit, takže roura je obvykle praktičtější (a rychlejší). Výhodou je, že si mezi těmito voláními můžete vypsat obsah souboru docasny_soubor a snáze tak pochopíte, proč roura dělá to co dělá. Předchozí příkaz by se tedy dal provést i takto:

ls -1 ~ > ~/docasny_soubor
wc -l < ~/docasny_soubor