Vstup a výstup procesů, přesměrování
Z MiS
„Write programs that do one thing and do it well.
Write programs to work together.
Write programs that handle text streams, because that is an universal interface.“
Douglas McIlroy
Obsah |
K čemu je přesměrování vstupů?
- Modelová situace: zpracovávám fotku pomocí utilit v příkazovém řádku.
- Potřebuji:
- vzít fotku → doostřit → upravit kontrast → uložit výslednou fotku
- Filozofie Unixu předepisuje jednoduché programy, které dělají jednu věc a dělají ji dobře.
- Měl bych tedy mít pro každý úkol samostatný program.
- Abych nemusel pokaždé ukládat a znovu načítat, mohly by si programy výsledky předávat přímo???
Procesy v Unixu a Linuxu
Přesměrování vstupů je vlastně způsob komunikace mezi procesy. Proces si můžeme představit jako černou skříňku s:
- standardním vstupem... za normálních okolností /dev/stdin, tedy klávesnice.
- standardním výstupem... za normálních okolností /dev/stdout, tedy obrazovka.
- standardním chybovým výstupem... za normálních okolností /dev/stderr, tedy obrazovka.
Vstup a výstup programů pak můžeme navzájem propojit.
Varianty přesměrování
- Přesměrování standardního výstupu do souboru
- program > soubor
- Zápis výstupu programu do souboru.
- Spustíme program s názvem program (tedy vznikne proces).
- Výstup procesu budeme zapisovat do souboru soubor.
- Pokud soubor neexistuje, vytvoří se. Pokud soubor již existuje, nová data přepíší ta, která v něm byla.
ls -l > ~/obsah_adresare.txt
- program >> soubor
- Stejně jako předchozí, ale pokud soubor již existuje, nově zapisovaná data se připojí na konec souboru.
echo "Druhy adresar:" >> ~/obsah_adresare.txt ls druhy -l >> ~/obsah_adresare.txt
- Přesměrování chybového výstupu do souboru
- program 2> soubor
- Chyby, které vypisuje program program se zapisují do souboru soubor.
cp a b 2> /dev/null mv archiv.tar.gz zalohy 2> ~/zaloha_chyby.log
- Přesměrování standardního vstupu
- program < soubor
- program čte data ze souboru soubor místo ze standardního vstupu (z klávesnice).
- Propojení programů
- program1 | program2
- Roura (anglicky pipe). Slouží k propojení dvou procesů. Je to tedy vlastně nástroj pro komunikaci mezi procesy.
- Spustí se program2. Jako vstup dostane „výstup z roury“. Pak se spustí program program1. Výstup z programu program1 se posílá do „roury“ jako „vstup roury“ a rourou se posílá ke zpracování programu program2.
ls | sort | head cat /etc/passwd | cut -d : -f 1 | sort
- Propojením několika programů pomocí roury vznikne kolona příkazů (anglicky pipeline).
Poznámka: Funkci použitých příkazů najdete v kapitole #Filtry.
- Další příklady
cat /proc/meminfo cat /proc/meminfo | head cat /proc/meminfo | head -n 1 > memory.txt cat /proc/meminfo | grep Free cat /etc/passwd | grep student
Speciální soubory
- Virtuální soubory reprezentující standardní vstup a výstup
- /dev/stdin... reprezentuje standardní vstup (klávesnici)
- /dev/stdout... reprezentuje standardní výstup (obrazovku)
- /dev/stderr... reprezentuje standardní chybový výstup (obrazovku)
- Pomocné
- /dev/null... jakákoli data zapsaná do tohoto souboru se zahodí
cp ~/ahoj.txt /home/student/ahoj.txt 2> /dev/null
- /dev/zero... kdykoli budeme číst z tohoto souboru, dostaneme znak s ASCII kódem 0. Můžeme číst libovolně dlouho.
- /dev/random... kdykoli budeme číst z tohoto souboru, dostaneme náhodný byte. Můžeme číst libovolně dlouho.
Viz také: Významné složky GNU/Linuxu.
Filtry
Jako filtr označujeme program, který čte data ze standardního vstupu a zapisuje výsledky na standardní výstup. Typické unixové programy se chovají jako filtry.
-
cat
... čte vstup a opisuje data na výstup -
grep
... čte vstup a opisuje na výstup jen řádky obsahující posloupnost znaků, zadanou jako parametr. Viz samostatná kapitolka. -
sed
... umí nahradit zadanou posloupnost znaků ve vstupu jinou posloupností (podobně jako nahrazování v textových editorech).- Viz například: LinuxConfig.org → Learning Linux Commands: Sed.
-
less
... stránkování výstupu, ukončujeme stiskem „q“
tar --help | less
-
head
... opíše na výstup jen prvních několik řádek vstupu- Bez přepínačů uvede prvních 10 řádků. Přepínačem můžeme stanovit, kolik řádků se má opsat na výstup.
head /proc/meminfo head -n 1 /proc/meminfo head -5 /proc/meminfo
-
tail
... opíše na výstup jen posledních několik řádek vstupu- Stejně jako u filtru
head
je výchozí hodnota 10 řádků a pomocí přepínače-n
můžeme specifikovat počet opsaných řádků.
- Stejně jako u filtru
tail /var/log/apache2/error_log tail -5 /var/log/apache2/error_log tail -n 8 /var/log/apache2/error_log
-
wc -l
... spočte počet řádek vstupu
ls | wc -l
-
tar
,gzip
-
tar
bere vstupní soubory, spojí je do jednoho proudu a vypíše na výstup. -
gzip
komprimuje/dekomprimuje soubory (metoda GZIP).
-
tar -c * | gzip > archiv.tar.gz tar -czf archiv.tar.gz * tar -xzf archiv.tar.gz
-
unzip
... dekomprimuje data ze vstupu (metoda ZIP) -
sort
cat /etc/passwd | cut -d : -f 1,5 | sort
-
cut
... vybere jen některé sloupce z tabulky. Viz samostatná kapitolka. -
nl
... očísluje řádky výstupu (šikovné u zdrojových kódů skriptů). -
tee
... opisuje vstup na obrazovku i do souboru či do dvou souborů
$ date | tee file1 file2 Thu Jun 10 11:10:34 CEST 2004 $ cat file1 Thu Jun 10 11:10:34 CEST 2004
-
uniq
... filtruje po sobě následující duplicitní řádky ze vstupu. -
tr
.. (TRanslate)- Nahrazuje ve vstupu zadané znaky jinými (podle tabulky) a vypisuje na výstup.
- Úkoly
- Vypište druhý řádek ze souboru
/proc/meminfo
.
Hrátky — filtr cat;)
- Program
cat
vlastně jen kopíruje data ze vstupu na výstup. - Pokud mu navíc zadáme jako parametr název souboru, čte data z tohoto souboru.
- Zamyslete se, co bude dělat, a vyzkoušejte:
cat
- Pozn.: ukončení vstupního souboru provedeme kombinací: Ctrl+D ;)
cat > /dev/stdout cat > pokus.txt cat /dev/stdin cat < /etc/passwd
Filtr grep
- Vybírá ze vstupu řádky, které obsahují zadaný text.
- Text může být specifikován přímo, nebo pomocí regulárních výrazů.
- Příklady speciálních znaků:
-
.
... nahrazuje jeden libovolný znak . -
*
... znamená, že předchozí znak se může opakovat libovolně — tedy i „nulakrát“ (může být vypuštěn úplně). -
\
... odebírá speciální význam následujícímu znaku -
[abx-y]
... libovolný ze znakůa
,b
ax
ažy
-
- Příklady použití
ls | grep a.[0-9]\.jpg
- Akceptuje soubory: ab3.jpg, a19.jpg, az0.jpg, a.0.jpg
- Ale neakceptuje soubory: ab.jpg, a.jpg, a1u.jpg, a9i.jpg, a.72jpg
- Úkoly
- Vypište ze souboru
/etc/passwd
řádek, který se týká aktuálně přihlášeného uživatele.
Pokus potřebujete vzory nahradit jinými, můžete využít
sed
. Filtr cut
- Na vstupu očekává textově zapsanou tabulku (podobný formát jako u souborů CSV).
- Vybere jen zvolené sloupce z „tabulky“.
- Parametry
-d :
- Zadává oddělovač jednotlivých „buněk tabulky“.
-f 1,3
- Zadává, které „sloupce“ z tabulky se mají vypsat.
- Příklad
- Typickým příkladem je práce se souborem /etc/passwd.
- Soubor /etc/passwd obsahuje údaje o uživatelích. Na každém řádku je jeden uživatel, údaje jsou odděleny znakem :.
cut /etc/passwd -d : -f 1,6
- Vypíše na obrazovku seznam uživatelských účtů a domovské složky uživatelů.
- Jedná se o sloupečky 1 a 6 z souboru /etc/passwd. Oddělovačem je standardně dvojtečka.
Zopakujte si
- Co je to „filtr“ v kontextu povídání o Linuxu a příkazové řádce?
- Co znamenají pojmy: kolona, roura (pipe).
- Na jaká zařízení jsou přesměrovány: standardní vstup, výstup a chybový výstup?
- Jaký je rozdíl mezi |, >, 2> a >>?
Cvičení — vyzkoušejte si!
- Vypište obsah aktuálního adresáře do souboru vypis.txt.
- Spočtěte, kolik souborů a složek je v podadresáři etc kořenového adresáře.
- V předchozím úkolu zahrňte jen soubory obsahující v názvu písmeno w.
- Výsledek předchozího úkolu připojte na nový řádek do souboru vypis.txt.
- Zobrazte seznam souborů v adresáři /bin. Pokud se výpis nevleze na obrazovku, zařiďte, aby se vypsala jen první obrazovka a výpisem šlo listovat (nahoru, dolů, o celé stránky, vyhledávat).
- Vypište posledních 5 souborů podle abecedy z podadresáře proc kořenového adresáře.
- Vypište ty řádky souboru cpuinfo podadresáře proc kořenového adresáře, které obsahují slovo model.
- Vypište uživatelská jména uživatelů registrovaných v systému s GNU/Linuxem. Každé jméno na jeden řádek. Jména seřaďte podle abecedy sestupně.
- Vypište třetí, čtvrtý, pátý a šestý řádek souboru .bash v domovském adresáři uživatele. Ostatní řádky ignorujte.
Řešení cvičení najdete úplně na konci textu.
Úkoly
- Úkol 1. — Formátovaný výstup
- Napište posloupnost příkazů, která vytvoří soubor ve tvaru:
- Několik pomlček
- Text
"Adresář:"
- Cesta k aktuálnímu adresáři
- Text
"Obsahuje soubory:"
- Výpis souborů, které jsou v aktuálním adresáři.
- Příklad výstupu:
--------------- Adresář: /home/student obsahuje soubory: Desktop Downloads a.txt ----------------
- Úkol 2. — Špatné filtrování?
- Chci vybrat z textového souboru uživatele s jednou konkrétní doménou (
seznam.cz
). - Proč nefunguje tento postup:
echo Eduard; Karásek; karaed@seznam.cz; 48 > data.txt echo Karel; Seznamicz; karel@seznamicz.cr; 25 >> data.txt echo Jana; Dolanská; dolanska@centrum.cz; 37 >> data.txt cat data.txt | grep @seznam.cz
- Opravte příkazy!
Řešení cvičení
ls > vypis.txt ls /etc | wc -l ls /etc | grep w | wc -l ls /etc | grep w | wc -l >> vypis.txt ls /bin | less ls /proc | sort | tail -5 cat /proc/cpuinfo | grep model cat /etc/passwd | cut -d : -f 1 | sort -r head -6 ~/.bash_history | tail -3
Související stránky
Zdroje
- codecoffee.com > Tips for Linux > Input/Output Redirection in Unix
- LinuxConfig.org → Learning Linux Commands: Sed