V příkazové řádce umíme napsat příkazy a známe prompt. Kromě toho dostáváme odpovědi a dodáváme vstupy do příkazu, tedy obvykle standardní vstupy a výstupy.
stdout
Když vám příkaz napíše něco zpět a je to to, co jste po něm chtěli, čtete si standardní výstup, tedy stdout.
jana@drak ~$ date
Thu Jun 25 22:19:13 CEST 2020
Řetězec Thu Jun 25 22:19:13 CEST 2020 je výstupem příkazu date a protože není specifikováno něco jiného, tiskne se do terminálu, tedy jako stdout.
stderr
Když vám příkaz napíše něco, co jste původně nechtěli, ale bohužel má pravdu, pak je to standardní chybový výstup, tedy stderr.
jana@drak ~$ ls /var/lock/lvm/
ls: cannot open directory '/var/lock/lvm/': Permission denied
jana@drak ~$ rm neco/
rm: cannot remove 'neco/': Is a directory
jana@drak ~$ rm -r neco/
rm: remove write-protected directory 'neco/'? y
rm: cannot remove 'neco/': Permission denied
jana@drak ~$ rm cosi
rm: cannot remove 'cosi': No such file or directory
Všechny příkazy zde skončily chybovým hlášením. Buď na něco nemám práva, špatný parametr nebo soubor vůbec neexistuje.
stdin
Když napíšete příkaz a on místo výstupu na vás kouká prázdným řádkem s kurzorem, potkali jste stdin.
Zatímco výstup potkáte při mnoha příkazech, standardní chybový potkáte doufám ne tak často, o standardní vstup nemusíte ani zavadit.
Slušný příkaz povětšinou jako parametr přijímá jméno souboru, ve kterém má něco udělat.
Jako příklad vezmu příkaz wc. Dám-li mu jako parametr nějaký soubor, pak jej vytiskne na standardní výstup.
Příkaz wc (tedy word count, co jste mysleli) vypsal, kolik má soubor maj.txt řádků, slov a bajtů. Když ale příkazu wc zapomenu dát parametr, očekává jej ze standardního vstupu.
jana@drak:~$ wc
ahoj
1 1 5
jana@drak:~$
Po spuštění příkazu se nic neděje, bliká na mě prázdný kurzor na začátku prázného řádku. Já do něj napsala řetězec ahoj, dala novou řádku a stiskla klávesovou zkratku ctrl-d, která je zkratkou pro symbol EOF (end of file). Tím jsem ukončila stdin a ten byl zpracován. Jeden řádek, jedno slovo, 5 bajtů. Proč 5? Protože "napsala jsem řetězec ahoj, dala novou řádku". Znak EOL (end of line) se počítá taky.
Přesměrování
Textové proudy jdou někam přesměrovat. Někam je v tomto případě do nějakého souboru, z nějakého souboru, případně jako vstup dalšího procesu.
Jednotlivé textové proudy mají své deskriptory, jejich použití se ukáže níže.
soubor
deskriptor
stdin
0
stdout
1
stderrout
2
Přesměrování vstupu
příkaz < nějaký_soubor vezme obsah souboru nějaký_soubor a použije jej jako vstup příkazu příkaz.
Příklad zdánlivě dává stejný výsledek jako wc maj.txt, nicméně v tomto případě příkaz wc neměl tušení, že pracuje v souboru maj.txt. Zdá se vám to málo? Vždyť jsem vám říkala, že se zas tak moc nepoužívá.
Přesměrování výstupu/chybového výstupu
příkaz > nějaký_soubor vezme výstup příkazu příkaz a místo, aby jej zobrazil na obrazovku, jak obvykle dělá, zapíše jej do souboru nějaký_soubor.
jana@drak:~$ date > kolik_je_hodin
jana@drak:~$ cat kolik_je_hodin
Tue Sep 22 23:25:14 CEST 2020
jana@drak:~$
Pokud soubor kolik_je_hodin neexistuje, přesměrování jej vytvoří. Pokud je plný, přepíše jej. Pokud potřebuju soubor nepřepisovat, ale přidávat na konec souboru, pak místo operátoru > použiju operátor >>, který neexistující soubor vytvoří, existující nepřepíše a přidá přesměrovaný výstup na jeho konec.
jana@drak:~$ cat neexistujici_soubor > vystup.txt
cat: neexistujici_soubor: No such file or directory
jana@drak:~$
Operátor > přesměrovává do souboru pouze standardní výstup a standardní chybový výstup vypisuje na obrazovku. V případě, že chcete přesměrovat chybový výstup, potřebujete jej specifikovat pomocí jeho dekriptoru (viz. tabulka výše), tedy dvojky. Velmi oblíbené použití je přesměrování standardního chybového výstupu do souboru /dev/null, tedy někam, kde ho už nikdy nepotkáte.
jana@drak:~$ cat neexistujici_soubor > vystup.txt
cat: neexistujici_soubor: No such file or directory
jana@drak:~$
Použití přesměrování je poměrně široké — s výhodou můžete plnit soubor výpisy nějakého procesu (logovat aktivitu). Nebo se zbavit výpisu do /dev/null, což je obvyklé právě u chybového výstupu. U některých (starých a jednoduchých) tiskáren je možné tisknout přímo textové proudy, které do ní posíláte, stačí je přesměrovat do souboru /dev/lp, těm novějším tiskárnám musíte poslat soubor ve formátu, kterému rozumí, ale ty staré hloupé umí vytisknout "ahoj", když jim jej pošlete.
Přehled přesměrování
notace
význam
<jméno_souboru
standarní vstup je přesměrován ze souboru
0<jméno_souboru
standarní vstup je přesměrován ze souboru
>jméno_souboru
standarní výstup je přesměrován do souboru
1>jméno_souboru
standarní výstup je přesměrován do souboru
2>jméno_souboru
standarní chybový výstup je přesměrován do souboru
&>jméno_souboru
oba standarní výstupy jsou přesměrovány do souboru
>>jméno_souboru
standarní výstup je připojen na konec souboru
1>>jméno_souboru
standarní výstup je připojen na konec souboru
2>>jméno_souboru
standarní chybový výstup je připojen na konec souboru
Roura
Existují pravidla pro vývoj Unixu/Linuxu
psát programy, které budou dělat právě jednu věc, a tu budou dělat dobře
psát programy tak, aby mohly navzájem spolupracovat
psát programy tak, aby povely přijı́maly hromadně ze vstupu v textové podobě
psát programy tak, aby výstupy produkovaly v textové podobě a mohly být použity jako vstupy dalšı́ch programů
Chcete-li vědět více, doporučuji knihu Raymond E. A.: Umění programovánı́ v Unixu, Computer Press 2004.
Z předchozích pravidel je zřejmé, že musí existovat nástroj, který spojí výstup jednoho programu s programem druhým. Tímto nástrojem je roura, tedy znak |
příkaz1 parametry | příkaz2 parametry
Standarní výstup prvního příkazu se stává vstupem pro druhý příkaz.