Unixová roura (anglickypipeline) jejednoduše použitelným prostředkem pro propojenívýstupu jednohoprocesu (spuštěnéhoprogramu) se vstupem druhého. Lze například propojit výstup příkazuls -l s příkazemgrep, který propustí pouze řádky začínající znakem d, takže zůstanou informace o podadresářích aktuálního adresáře:
$ls-l|grep^d
Použitínepojmenované (anonymní) roury (Unix poskytuje taképojmenované roury) doplňuje možnostpřesměrovánístandardních proudů do nebo zesouboru, jehož jméno stanovujeuživatel až v okamžiku zadánípříkazu, o velmi mocný prostředek, který zároveň zpřístupňujemultitasking.
Dokolony propojit i více než dva procesy a tak vytvářet novévlastnosti:
$mancp|tr-cs'[:alnum:]''\n'|sort|uniq-c|sort-rn|less
(příkaz zobrazuje po jednotlivých obrazovkáchpočty výskytů jednotlivých slovních tvarů vmanuálové stráncepříkazu cpsetříděné od slov s nejvyšším počtem výskytů).
Unixové roury jsou nápaditou formou a implementací staršího konceptusoftwarových rour, která byla s určitými omezeními převzata do dalších operačních systémů (DOS,Microsoft Windows,OpenVMS).
Softwarové roury jsou rozhraním nebo datovým kanálem mezi dvěma entitami zpracovávajícímidata (programy,vlákny,koprogramy atd.), jenžkomunikaci zajišťuje v jednom směru a funguje v režimufronty[1]. Unixová roura, tak jako jiné softwarové roury, představuje pohodlný prostředek realizacepřesměrování dat z výstupu jedné entity zpracovávající data na vstup jiné.
Od svých mladších derivátů se unixová roura nejvýrazněji odlišuje tím, že je s ní neodmyslitelně spojeno použitívyrovnávací paměti (bufferu), díky čemuž tato vedle bezobslužného a bezúdržbového postupování dat meziprogramy[2], jež další typy roury převzaly především, nabízí takévýkonovou optimalizaci, tedy navýšení objemu dat, kterýkolonou – skupinouprocesů zřetězených rourami – proteče za jednotku času.[3]
Unixové roury se dělí naanonymní apojmenované; anonymní jsou starší než pojmenované a nazývají se téžnepojmenované,konvenční nebotradiční. Pojednává-li se o rouře, aniž by tato byla rozvitapřívlastkem, a je-li z kontextu zřejmé, že řeč je o rouře unixové, je s vysokou pravděpodobností myšlena anonymní (unixová) roura.
Roura je (vunixových systémech všeobecně) implementována jakokruhový buffer o celkové velikosti 64KiB, který je po 4 KiB rozdělený na šestnáct jednotek. Čtení a zápis do roury jsou vybavenysynchronizací, kteráproces tzv.zablokuje v případě, kdy není co číst, resp. kam zapisovat.
Velmi těsné propojení rour sesouborovým systémem –unixové systémy se každou entitu snaží abstrahovat jakosoubor, nebo jako proces – do roury umožňuje zapisovat a z ní číst těmisystémovými voláními, jimiž se provádí zápis do souboru a čtení z něj.
Nápadný rozdíl oproti práci se soubory spočívá v tom, že anonymní roura má oddělenýsouborový deskriptor pro zápis od souborového deskriptoru pro čtení – s anonymní rourou jsou propojeny souborové deskriptory dva. Příčinu této odlišnosti lze s úspěchem hledat v tom, že zatímco se souborem lze plnohodnotně pracovat prováděním jen čtení nebo jen zápisu, upotřebení anonymní roury má smysl jen tehdy, když se čte i zapisuje (kdatům by se později nebylo možné dostat, jelikož by se na ně nebylo jak odkázat).
Další vlastností, jež práci s rourami odlišuje od práce se soubory, je fakt, že s rourou se zachází jako sezařízením znakovým, zatímco se souborem jako sezařízením blokovým. V důsledku to znamená, že zápis do roury nelze opravit či aktualizovat (jednou předaná data přepsat) a data přečtená z roury přečíst znova (již byla odebrána).
Anonymní roury nemají vlastníidentifikátor; přístupné jsou toliko prostřednictvímsouborových deskriptorů, pročež je možné je využít jen kekomunikaci meziprocesy, které jsou (přímými nebo nepřímými) potomky procesu, jenž je vytvořil, a tímto procesem (mezi libovolnou dvojicí procesů z této množiny) – jiným způsobem, než skrze vytvoření potomka (systémové volánífork
[4]), totižsystémovým voláním vytvářejícím anonymní rouru (pipe
[5]) získané souborové deskriptory mezi procesy nelze distribuovat.
K anonymním rourám se váže znaksvislé čáry („|“) – právě jím uživatelshellu sděluje, že má zájem o použití anonymní roury; po levé a pravé straně se potom nacházejí názvy a parametrizaceprogramů, jež k rouře mají přistupovat – nalevo je jmenována entita do rourydata vkládající a napravo entita z roury data odebírající. Proces shellu přitom plní roli rodičovského procesu, mezi nímž a jehož potomky jekomunikace anonymní rourou možná pouze, který žádá o vytvoření procesů za účelem vykonání programů v koloně podle předpisuuživatele; součástí jeho agendy je připojenístandardního výstupu do roury zapisujícího programu na souborový deskriptor roury pro zápis a svázánístandardního vstupu z roury čtecího programu se souborovým deskriptorem roury pro čtení.
S anonymními rourami se pojí taktéž výrazskupina procesů. Procesy participující v koloně patří do téže skupiny procesů, aby celou kolonu bylo možné snadněji spravovat, kupř. stanovovat priority pro plánování na procesor; v rámci skupiny procesůoperační systém rovněž může hledat tzv. úzká hrdla, a právě je co do priority s výhledemoptimalizace výkonu celé kolony vpřidělování procesorového času zvýhodnit.
$history|grep"^java "|wc-l
Příkaz vypíše, kolikrát (za sledovanou historii – např. posledních 500 příkazů)uživatel spustilprogramjava
; předpokládá se, že všechna spuštění proběhla se slovemjava na začátku příkazu[6].
Programgrep
v toku potlačuje řádky, které nevyhovují specifikovanémuregulárnímu výrazu;mezera na konci vyhledávanéhořetězce je začleněna proto, aby z proudu byla vyňata volání programů, jejichž názvy řetězcemjava pouze začínají (do této skupiny spadá kupř. primárníkompilátor jazykaJava – programjavac
), znakstříšky udává, že shoda může být uznána pouze tehdy, dojde-li k ní na začátku posuzovaného řetězce.
Programwc
s přepínačem-l
celý text (všechny jeho řádky) nahrazuje jednímcelým číslem, odpovídajícím počtu řádků přijatých nastandardním vstupu.
Níže uvedený příkaz demonstruje typické použití programuless
, jenž byl pro nasazení na konci kolony anonymních rour přímo navržen. Náplní jeho práce je v textu zestandardního vstupu umožnit listovat (scrollovat), abyuživatel (bez použití složitějších nástrojů) byl schopen přečíst tu úvodní část výstupu, která se nevejde naobrazovku, i v těchtextových shellech, jež nedisponují posuvníkem a dostatečnoupamětí.[7] Programless
je následovníkem programumore
, který dovoluje zachytit celý výstup, ale ne se po odstránkování vracet. V kontextu kolony jeless
zajímavý tím, že pro to, aby mohl začít řádně fungovat, vyžaduje ukončení toku do něj vstupujícíchdat (uzavřenísouborového deskriptoru roury pro zápis).
$ls-l|less
Programls
provádí výpis obsahu aktuálníhoadresáře (nastandardní výstup).
$wget-q-O'-''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-2-3'-''/usr/share/dict/words'
Zadání směřuje k odhalenípřeklepů nawebové stránce, specifikovanéURL. Následuje popis jednotlivých částí příkazu:
wget
z adresyhttp://en.wikipedia.org/wiki/Pipeline_(Unix)
stáhnehypertextový dokument a zapíše jej (přepínač-O
) nastandardní vstup (parametr-
); přepínač-q
potlačí výstup běhových informací, implicitně předávaný nastandardní chybový výstup.sed
všechny znaky, které nejsou písmenemanglické abecedy nebomezerou, nahradí mezerou.tr
převede všechna velká písmena na malá a všechny mezery na znak konce řádku. Každé „slovo“ (posloupnostznaků anglické abecedy) tedy bude na samostatném řádku.grep
z proudu odstraní řádky, které neobsahují žádné písmeno anglickéabecedy.sort
z toku vyjme všechny duplicitní řádky (přepínač-u
) a ponechanéabecedně setřídí.comm
text upraví takovým způsobem, že výstup bude roven rozdílu[8]množiny standardního vstupu (parametr-
) a množinysouboru/usr/dict/words
[9], kde prvky množin tvoří jednotlivé řádky (přepínač-2
z proudu vyloučí řádky obsažené výhradně ve druhém jmenovaném souboru, přepínač-3
tok zbaví řádků vyskytujících se v obou souborech).[10]Znakzpětného lomítka („\“) bezprostředně předcházející odřádkováníinterpretu příkazů sděluje, že zadání příkazu nebylo ukončeno (jen se, kvůli přehlednosti, ve formulaci jeho další části pokračuje na následujícím řádku; odřádkování je kromě postoupení příkazu ke zpracování také funkce klávesy↵ Enter).
S koncepcí anonymní unixové roury, jež byla poprvé popsána vmanuálových stránkách Unixu verze 3, přišelDouglas McIlroy; již první návrh obsahoval znaksvislé čáry. První implementaci provedlKen Thompson v r.1973, a to dounixového shelluThompson shell.[11]
Později bylo schéma převzato do dalšíchoperačních systémů, např.AmigaOS,BeOS,Mac OS X[12],MS-DOSu,OpenVMS,OS/2 neboWindows, a stalo senávrhovým vzoremroury a filtry.
Pojmenované roury jsou řešenímmeziprocesové komunikace, které má prvky předávání dat anonymní rourou i vlastnosti provádění téže činnosti cestou řádnýchsouborů – pojmenované roury jsou globálněadresovatelné (mají v celémsystému unikátníidentifikátor), a jejich jména je třeba spolupracujícím procesům předávat, ale není nutné se starat, aby pokus o uložení dat do nich neselhal z důvodu nedostatku volného místa na diskové jednotce, a úložiště (nikoli ve smyslu řádného čtení) vyprazdňovat. Vznik a zánik pojmenované roury není vázán životním cyklem kteréhokoliprocesu, který z ní může číst, nebo do ní zapisovat; probíhá zcela nezávisle. Jako položka vsouborovém systému pojmenovaná roura podléhá koncepcipřístupových práv.
Pojmenované roury jsou vhodné pro jiné úlohy, než roury anonymní.
java
je možné spustit také zápisem/usr/bin/java
(na některýchdistribucích může být umístění programu jiné).less
se používá uvnitř programů, které s většími objemy textu pracují nativně (např.man
neboinfo
)./usr/share/dict/words
.comm
oba vstupnísoubory očekává seřazené.pipe
odOpenGroup (Single UNIX Specification)fork
odOpenGroup (Single UNIX Specification)mkfifo
– zřízenípojmenované roury