
| Název školy: | Vyšší odborná škola a Střední průmyslová škola, Božetěchova 3 |
| Autor: | Ing. Marek Nožka |
| Anotace: | Standardní vstup, výstup a jejich přesměrování |
| Vzdělávací oblast: | Informační a komunikační technologie |
| Předmět: | Počítačové sítě a komunikační technika (PSK) |
| Tematická oblast: | Operační systém Linux/Unix |
| Výsledky vzdělávání: | Žák přesměrovává vstupy/výstupy z/do souboru, používá roury |
| Klíčová slova: | Linux, Unix, shell, roura, pipe, stdin, stdout, stderr |
| Druh učebního materiálu: | Online vzdělávací materiál |
| Typ vzdělávání: | Střední vzdělávání, 4. ročník, technické lyceum |
| Ověřeno: | VOŠ a SPŠE Olomouc; Třída: 4L |
| Zdroj: | Vlastní poznámky, Vilém Vychodil: Linux Příručka českého uživatele |
Jedním ze základních stavebních kamenů operačního sytému Unix je následující přístup:

V Unixu má každý proces (program) standardní
vstup stdin, standardní výstup stdout a standardní chybový výstup
stderr. Vstup standardně čte z klávesnice vždy, když uživatel stiskne
klávesu Enter. Výstup a chybový výstup se během běhu programu vypisuje na
terminál, tedy na obrazovku.
$ wc
Mily studente,
dnes se ucime o OS Unix
Hezky den
^D
>>>> 4 10 50
Například program wc čte text zadaný z klávesnice a
po jeho ukončení (klávesová zkratka Ctrl+D vkládá znak konce souboru) vypíše
počet znaků, slov a řádků.

Všechny programy ale nutně nemusí stdin používat. Například program
ls, který vypisuje obsah adresáře žádný
standardní vstup nečte.
Výstup každého programu je možné přesměrovat do souboru pomocí metaznaku >:
>SOUBOR |
standardní výstup je přesměrován do souboru |
>>SOUBOR |
standardní výstup je připojen na konec souboru |
2>SOUBOR |
standardní chybový výstup je přesměrován do souboru |
2>>SOUBOR |
standardní chybový výstup je připojen na konec souboru |
&>SOUBOR |
oba standardní výstupy jsou přesměrovány do souboru |
Například:
$ ls . blah
>>>>ls: nelze přistoupit k blah: Adresář nebo soubor neexistuje
>>>>.:
>>>>index.pl inout.ditaa inout.png
Program vypíše obsah aktuálního adresáře a adresáře blah. Protože ale adresář
blah neexistuje program vypíše na chybový výstup chybové hlášení.

Nyní výstup přesměrujeme do souboru obsah.txt. Chybové hlášení je stále vidět
na terminálu (obrazovce), ale výpis adresáře se provedl do souboru:
$ ls . blah >obsah.txt
>>>>ls: nelze přistoupit k blah: Adresář nebo soubor neexistuje

Jestliže přesměrujeme do souboru pouze chybový výstup, situace se otočí:
$ ls . blah 2>chyba.txt
>>>>.:
>>>>index.pl inout.ditaa inout.png

Obsah souboru můžeme vypsat pomocí příkazu cat:
$ cat obsah.txt chyba.txt
>>>>.:
>>>>index.pl
>>>>inout.ditaa
>>>>inout.png
>>>>obsah.txt
>>>>/bin/ls: nelze přistoupit k blah: Adresář nebo soubor neexistuje
Při přesměrování lze místo jména SOUBORu použít souborový deskriptor.
Ten se zadává ve formátu &CISLO, kde CISLO označuje deskriptor.
| deskriptor | význam |
|---|---|
0 |
standardní vstup |
1 |
standardní výstup |
2 |
standardní chybový výstup |
Příkaz:
$ ls . blah >>vystup.txt 2>&1
Přesměruje standardní výstup na konec souboru a zároveň přesměruje chybový
výstup na standardní výstup, takže se v souboru vystup.txt objeví stdout(1)
i stderr(2).

Vstup programu lze přesměrovat pomocí metaznaku <. Proces (program) potom
nebude číst vstupní data z klávesnice ale ze souboru.
Jako příklad si uvedeme krátký program v jazyce Python, který provede součet všech čísel zadaných na vstup.
1 #!/usr/bin/python
2 # -*- coding: utf8 -*-
3 # Soubor: soucet.py
4 # Licence: GNU/GPL
5 # Popis: Program provede součet všech čísel, které přečte z stdin
6 ############################################################################
7 import sys
8 from sys import stdin, stdout, stderr
9 ############################################################################
10 soucet=0
11 while True:
12 try:
13 line = raw_input()
14 cisla = line.split()
15 for c in cisla:
16 c=float(c)
17 soucet+=c
18 except EOFError:
19 print soucet
20 exit(0)
21 except KeyboardInterrupt:
22 stderr.write("Program prerusen uzivatelem\n")
23 exit(1)
24 except:
25 stderr.write("ERROR: '{}' neni cislo\n".format(c))
26 exit(2)
`--> stáhnout
./soucet.py
1 2 3
4 5
>>>>15.0
Čísla, která se mají sečíst můžeme zapsat do souboru sectito.txt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
90 91 92 93 94 95 96 97 98 99 100
`--> stáhnout
Potom stačí jednoduše zavolat:
./soucet.py <sectito.txt
>>>>5050.0
Často je velice užitečné spojit dva programy a výstup jednoho přesměrovat na
vstup druhého. Slouží k tomu mechanizmus, který se označuje jako
roura (pipe). Pro zřetězení několika programů pomocí
roury se používá metaznak |.
ls *.txt | wc -l
>>>> 15
Výstup programu ls je přesměrován na vstup programu wc, který počítá řádky.
Výsledkem je tedy počet souborů s příponou .txt.

Takto lze spojovat do kolony i více programů. Například:
ls -l *.png | cut -d ' ' -f 5,10 | sort -n
>>>>3674 roura.png
>>>>3842 wc.png
>>>>5091 oba.png
>>>>5123 blah.png
>>>>5909 obsah.png
>>>>5947 chyba.png
>>>>6417 inout.png
Program ls podrobně vypíše soubory s příponou .png, program
cut vybere z výpisu jen dva sloupce a program
sort je seřadí podle velikosti.
Rouru není možné použít vždy. Je to například pokud spolu chtějí komunikovat dva procesy, které spouští vždy jiný uživatel. V těchto případech je možné použít pojmenovanou rouru. Tu je třeba nejprve vytvořit a poté je možné s ní pracovat jako by to byl soubor.
$ mkfifo /tmp/mojetrubka
$ chmod a+r /tmp/mojetrubka
$ ls -l *.png | cut -d ' ' -f 5,10 >/tmp/mojetrubka
Jiný uživatel potom může z roury číst
$ sort -n </tmp/mojetrubka