Roura (Unix)
Roura, trubka, kolona, anonymní roura, konvenční roura (anglicky pipeline) je v unixových systémech původním nástrojem pro spojování procesů do řetězce pomocí vzájemného propojení standardních proudů tak, že je vždy výstup (stdout) procesu nasměrován přímo do vstupu (stdin) následujícího procesu. Rourami jsou často spojovány programy, které nazýváme filtry. Jde o jednosměrnou meziprocesovou komunikaci (IPC), pro jejíž vytvoření se používá fronta FIFO, která se vytváří u příbuzných procesů a automaticky zaniká po jejich ukončení. Moderní implementace umožňují i obousměrné přenosy dat a dokonce i přenášet data mezi více počítači.
Koncept použití rour vynalezl Douglas McIlroy pro unixový shell a byl pojmenován podle analogické funkce se skutečnými rourami (trubkami). Univerzálnější je pojmenovaná roura, pomocí které lze propojit i nepříbuzné procesy.
Obsah |
Implementace [editovat]
Roura je implementovaná jako (kruhová) fronta o velikosti jednotek 4kB (v Linuxu). Velmi těsné propojení rour se souborových systémem umožňuje pracovat s rourou pomocí základních souborových operací. Zápis a čtení probíhá souborově orientovanými operacemi. Jediným rozdílem oproti souborům je, že s rourou jsou propojeny dva deskriptory otevřených souborů. Jeden je určen pro zápis (vstup do roury) a druhý pro čtení (výstup z roury).
Nad rourou existuje jednoduchá synchronizace, která zapisující proces zablokuje, pokud je roura plná a naopak čtecí proces zablokuje, pokud je prázdná.
Nepojmenované roury [editovat]
Nepojmenované (anonymní) roury nemají vlastní identifikátor a jsou přístupné pouze prostřednictvím souborových deskriptorů. Tyto roury lze využít jen pro komunikaci mezi libovolnými procesy, které jsou potomky procesu, jenž rouru vytvořil. Anonymní roury jsou využívány k vytváření tzv. kolon, tedy spojení jednoduchých příkazů pomocí rour za účelem úpravy vstupních dat. Kopírování z jednoho procesu do druhého je prováděno prostřednictvím rutin jádra. Na zdrojové straně zápis rutinou write a na straně druhé čtení rutinou read.
Příklad kolony [editovat]
history | grep java | wc -l
Tato kolona vypíše kolikrát uživatel spustil program java.
Další jednoduchý příklad [editovat]
V příkladu uvedeném níže příkaz ls vypisuje obsah adresáře a less je interaktivní program, který umožňuje prohlížet obsah svého vstupu po jednotlivých stránkách, vracet se a vyhledávat. Kolona příkazů v příkladu tedy umožní prohlížet celý výpis postupně, i když se nevejde na jednu obrazovku terminálu.
ls -l | less
Vytváření kolon (rour) s využitím příkazů less (nebo jeho jednodušší a starší variantou more) je velmi často používána pro prohlížení potenciálně velkých textových výstupů programů, které by jinak odrolovaly nahoru mimo obrazovku terminálu a byly ztraceny. Stejně tak jsou tyto dva programy využívány uvnitř programů, které prezentují větší objemy textu (například příkaz man).
Složitější příklad [editovat]
V následujícím příkladu je implementována kolona příkazů, která zkontroluje překlepy na webové stránce zadané pomocí URL odkazu. Vysvětlení následuje za příkladem (na některých systémech je databáze slov v souboru /usr/share/dict/words).
curl "http://en.wikipedia.org/wiki/Pipeline_(Unix)" | \ sed 's/[^a-zA-Z ]/ /g' | \ tr 'A-Z ' 'a-z\n' | \ grep '[a-z]' | \ sort -u | \ comm -23 - /usr/dict/words
Poznámka: znak zpětného lomítka („\“) umožňuje rozdělit jeden dlouhý řádek na více řádků, i když interpret příkazů je takto chápe jako jeden řádek (jeden složený příkaz, tj. jednu kolonu příkazů) a bude zpracován najednou.
Popis jednotlivých kroků zpracování datového proudu v koloně příkazů:
curlstáhne stránku v podobě HTML (lze použít i příkazwget)sedodstraní všechny znaky, které nejsou písmena nebo znak mezery a nahradí je mezeroutrzmění všechna velká písmena na malá a změní všechny mezery v textu na znak konce řádku (takže každé „slovo“ bude na zvláštním řádku)grepvypíše pouze řádky, které obsahují alespoň jedno písmeno (odstraní prázdné řádky)- sort všechna „slova“ abecedně setřídí a přepínač
-uodstraní všechny duplicitní výskyty (každé „slovo“ bude na výstupu jen jednou) commnalezne společné řádky v obou souborech, přepínač-23potlačí výstup řádků, které se vyskytují pouze v druhém vstupním souboru a ty, které se vyskytují v obou souborech, takže na výstupu budou jen ty „slova“, které jsou pouze v prvním souboru. Protože je jako parametr použit znak-, je prvním souborem standardní vstup (výstup předchozího příkazu) a druhým souborem je soubor se slovy/usr/dict/words. Proto budou na výstupu slova, která se nacházejí na webové stránce, ale nejsou obsažena v souboru/usr/dict/words.
Speciální znak svislá čára („|“) na příkazovém řádku znamená, že shell má propojit standardní výstup příkazu na jeho levé straně se standardním vstupem příkazu na jeho pravé straně (dojde k vytvoření roury).
Historie [editovat]
Koncept použití rour a použití znaku svislá čára („|“) vynalezl Douglas McIlroy, jeden z autorů prvních unixových shellů, když si všiml, jak mnoho času tráví zpracováním výstupu jednoho programu jako vstupu do jiného programu. V roce 1973 jeho ideu implementoval Ken Thompson, když přidal roury do operačního systému Unix a shellu Thompson shell.[1]
Ikona robota Automator v operačním systému Mac OS X firmy Apple, který také využívá daný koncept, drží rouru.
Ostatní operační systémy [editovat]
- Související informace naleznete v článku Roura (software).
Idea roury byla převzata ostatními operačními systémy, často včetně stejného zápisu, jako například DOS, OS/2, Microsoft Windows, Mac OS X, BeOS a další. Stala se konceptem softwarového designu „roury a filtry“.
Reference [editovat]
- ↑ http://www.linfo.org/pipe.html Pipes: A Brief Introduction by The Linux Information Project (LINFO)
Související články [editovat]
- Pojmenovaná roura – pojmenovaná roura pro spojení mezi nepříbuznými procesy
- Soket – pokročilejší IPC s možností obousměrné komunikace i mezi procesy na různých počítačích
Externí odkazy [editovat]
- http://www.opengroup.org/onlinepubs/9699919799/functions/pipe.html – manuálová stránka funkce
pipe()od OpenGroup (Single UNIX Specification) - http://linux.die.net/man/2/pipe – manuálová stránka funkce
pipe()pro Linux