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ě.
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.
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
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 (zřídkakdy) 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 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
Dalším způsobem, jak si poznamenat do souboru data, aniž bychom museli přerušovat rouru je příkaz tee.
cat – vypíše zadané soubory
tac – vypíše zadané soubory s přehozeným pořadím řádků
rev – vypíše zadané soubory s převrácenými řádky
cut – vypíše jen zadané sloupce ze souboru
sort – setřídí řádky souboru
uniq – vypíše opakující se řádky
tr – nahradí výskyt zadaných znaků jinými znaky
join – spojí soubory podle společného sloupce
last – výpis posledních přihlášení (není v POSIXu)
who – zobrazí přihlášené uživatele
ps – vypíše procesy bežící na terminálu
getent passwd – vypíše seznam všech uživatelů v síti
(není v POSIXu; labová specialita)
ls > obsah
head -n17 /etc/passwd | tail -n+13
wc < /etc/passwd > ~/vystup-wc
echo -e "/tmp\n/etc\n/" > adresare
Příkaz vypíše obsah aktuálního adresáře, protože ls ignoruje svůj standardní vstup.
getent passwd | cut -d: -f1,5
getent passwd | cut -d: -f5 | cut -d\ -f1 | sort -u | wc -l
getent passwd | cut -d: -f5 | sort | uniq -d
getent passwd | cut -d: -f5 | sort | uniq -d | sort -k2
Pozn.: Ve skutečnosti třídíme podle druhého jména, přičemž příjmení může být i na nějakém dalším místě. Řešení třídící opravdu podle příjmení je se zatím probranými prostředky složitější, i když ne nemožné.
< /etc/passwd tr 'a-zA-Z' 'c-zabC-ZAB'