Roura (Unix)
Unixová roura (anglicky pipeline) je jednoduše použitelným prostředkem pro propojení výstupu jednoho procesu (spuštěného programu) se vstupem druhého. Lze například propojit výstup příkazu ls -l s příkazem grep, 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žnost přesměrování standardních proudů do nebo ze souboru, jehož jméno stanovuje uživatel až v okamžiku zadání příkazu, o velmi mocný prostředek, který zároveň zpřístupňuje multitasking.
Do kolony propojit i více než dva procesy a tak vytvářet nové vlastnosti:
$ man cp | tr -cs '[:alnum:]' '\n' | sort | uniq -c | sort -rn | less
(příkaz zobrazuje po jednotlivých obrazovkách počty výskytů jednotlivých slovních tvarů v manuálové stránce příkazu cp setříděné od slov s nejvyšším počtem výskytů).
Unixové roury jsou nápaditou formou a implementací staršího konceptu softwarových rour, která byla s určitými omezeními převzata do dalších operačních systémů (DOS, Microsoft Windows, OpenVMS).
Implementace
[editovat | editovat zdroj]Softwarové roury jsou rozhraním nebo datovým kanálem mezi dvěma entitami zpracovávajícími data (programy, vlákny, koprogramy atd.), jenž komunikaci zajišťuje v jednom směru a funguje v režimu fronty[1]. Unixová roura, tak jako jiné softwarové roury, představuje pohodlný prostředek realizace př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 mezi programy[2], jež další typy roury převzaly především, nabízí také výkonovou optimalizaci, tedy navýšení objemu dat, který kolonou – skupinou procesů zřetězených rourami – proteče za jednotku času.[3]
Unixové roury se dělí na anonymní a pojmenované; anonymní jsou starší než pojmenované a nazývají se též nepojmenované, konvenční nebo tradiční. Pojednává-li se o rouře, aniž by tato byla rozvita pří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 (v unixových systémech všeobecně) implementována jako kruhový buffer o celkové velikosti 64 KiB, který je po 4 KiB rozdělený na šestnáct jednotek. Čtení a zápis do roury jsou vybaveny synchronizací, která proces tzv. zablokuje v případě, kdy není co číst, resp. kam zapisovat.
Velmi těsné propojení rour se souborovým systémem – unixové systémy se každou entitu snaží abstrahovat jako soubor, nebo jako proces – do roury umožňuje zapisovat a z ní číst těmi systé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 (k datů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 se zařízením znakovým, zatímco se souborem jako se zaří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í roura
[editovat | editovat zdroj]Anonymní roury nemají vlastní identifikátor; přístupné jsou toliko prostřednictvím souborových deskriptorů, pročež je možné je využít jen ke komunikaci mezi procesy, 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 znak svislé čáry („|“) – právě jím uživatel shellu sděluje, že má zájem o použití anonymní roury; po levé a pravé straně se potom nacházejí názvy a parametrizace programů, jež k rouře mají přistupovat – nalevo je jmenována entita do roury data 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 je komunikace anonymní rourou možná pouze, který žádá o vytvoření procesů za účelem vykonání programů v koloně podle předpisu už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ýraz skupina 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ýhledem optimalizace výkonu celé kolony v přidělování procesorového času zvýhodnit.
Jednoduchý příklad
[editovat | editovat zdroj]$ history | grep "^java " | wc -l
Příkaz vypíše, kolikrát (za sledovanou historii – např. posledních 500 příkazů) uživatel spustil program java
; předpokládá se, že všechna spuštění proběhla se slovem java na začátku příkazu[6].
Program grep
v toku potlačuje řádky, které nevyhovují specifikovanému regulá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ězcem java pouze začínají (do této skupiny spadá kupř. primární kompilátor jazyka Java – program javac
), znak stříšky udává, že shoda může být uznána pouze tehdy, dojde-li k ní na začátku posuzovaného řetězce.
Program wc
s přepínačem -l
celý text (všechny jeho řádky) nahrazuje jedním celým číslem, odpovídajícím počtu řádků přijatých na standardním vstupu.
Další jednoduchý příklad
[editovat | editovat zdroj]Níže uvedený příkaz demonstruje typické použití programu less
, jenž byl pro nasazení na konci kolony anonymních rour přímo navržen. Náplní jeho práce je v textu ze standardního vstupu umožnit listovat (scrollovat), aby uživatel (bez použití složitějších nástrojů) byl schopen přečíst tu úvodní část výstupu, která se nevejde na obrazovku, i v těch textových shellech, jež nedisponují posuvníkem a dostatečnou pamětí.[7] Program less
je následovníkem programu more
, který dovoluje zachytit celý výstup, ale ne se po odstránkování vracet. V kontextu kolony je less
zajímavý tím, že pro to, aby mohl začít řádně fungovat, vyžaduje ukončení toku do něj vstupujících dat (uzavření souborového deskriptoru roury pro zápis).
$ ls -l | less
Program ls
provádí výpis obsahu aktuálního adresáře (na standardní výstup).
Složitější příklad
[editovat | editovat zdroj]$ 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ů na webové stránce, specifikované URL. Následuje popis jednotlivých částí příkazu:
wget
z adresyhttp://en.wikipedia.org/wiki/Pipeline_(Unix)
stáhne hypertextový dokument a zapíše jej (přepínač-O
) na standardní vstup (parametr-
); přepínač-q
potlačí výstup běhových informací, implicitně předávaný na standardní chybový výstup.sed
všechny znaky, které nejsou písmenem anglické abecedy nebo mezerou, nahradí mezerou.tr
převede všechna velká písmena na malá a všechny mezery na znak konce řádku. Každé „slovo“ (posloupnost znaků 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žiny souboru/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]
Znak zpě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).
Historie
[editovat | editovat zdroj]S koncepcí anonymní unixové roury, jež byla poprvé popsána v manuálových stránkách Unixu verze 3, přišel Douglas McIlroy; již první návrh obsahoval znak svislé čáry. První implementaci provedl Ken Thompson v r. 1973, a to do unixového shellu Thompson shell.[11]
Později bylo schéma převzato do dalších operačních systémů, např. AmigaOS, BeOS, Mac OS X[12], MS-DOSu, OpenVMS, OS/2 nebo Windows, a stalo se návrhovým vzorem roury a filtry.
Pojmenovaná roura
[editovat | editovat zdroj]Pojmenované roury jsou řešením meziprocesové komunikace, které má prvky předávání dat anonymní rourou i vlastnosti provádění téže činnosti cestou řádných souborů – pojmenované roury jsou globálně adresovatelné (mají v celém systé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éhokoli procesu, který z ní může číst, nebo do ní zapisovat; probíhá zcela nezávisle. Jako položka v souborovém systému pojmenovaná roura podléhá koncepci přístupových práv.
Pojmenované roury jsou vhodné pro jiné úlohy, než roury anonymní.
Odkazy
[editovat | editovat zdroj]Reference
[editovat | editovat zdroj]- ↑ Charakteristickým rysem fronty je, že odběratel data přebírá v tom pořadí, ve kterém je zdroj vložil.
- ↑ Starší způsob předávání dat mezi programy – ukládání průběžných dat v souborech – v porovnání s anonymní rourou obsluhu zatěžuje vedlejšími úkony, kupř. pojmenováváním souborů, informováním entit zpracovávajících data o těchto názvech, sledováním, zda pro soubory bude stačit paměť, a jejich vyprázdňováním, popř. mazáním.
- ↑ Použití vyrovnávací paměti (bufferu) jisté optimalizační účinky unixové roury garantuje i v prostředích, kde není možný současný (paralelní) běh více programů, což by se pro využití potenciálu tzv. bufferování mohlo zdát nezbytné – procesorový čas se ušetří menším objemem synchronizací.
- ↑ http://linux.die.net/man/2/fork – vytvoření procesu potomka
- ↑ http://linux.die.net/man/2/pipe – vytvoření anonymní roury
- ↑ Program
java
je možné spustit také zápisem/usr/bin/java
(na některých distribucích může být umístění programu jiné). - ↑ Program
less
se používá uvnitř programů, které s většími objemy textu pracují nativně (např.man
neboinfo
). - ↑ Rozdíl množin A a B je množina všech prvků množiny A, jež nejsou prvky množiny B.
- ↑ Program
comm
oba vstupní soubory očekává seřazené. - ↑ http://www.linfo.org/pipe.html Pipes: A Brief Introduction by The Linux Information Project (LINFO)
- ↑ Ikona robota [[Automator (software)|]] v operačním systému Mac OS X firmy Apple drží rouru.
Související články
[editovat | editovat zdroj]- Deskriptor souboru
- Operační systém
- Pojmenovaná roura
- Proces
- Roura
- Roura
- Skupina procesů
- Soket – pokročilejší IPC s možností obousměrné komunikace i mezi procesy na různých počítačích
- Soubor
- Standardní proudy
- Synchronizace
- Systémové volání
- Unix
- Zařízení
Externí odkazy
[editovat | editovat zdroj]- http://www.opengroup.org/onlinepubs/9699919799/functions/pipe.html – manuálová stránka systémového volání
pipe
od OpenGroup (Single UNIX Specification) - http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html – manuálová stránka systémového volání
fork
od OpenGroup (Single UNIX Specification) - http://linux.die.net/man/1/mkfifo – manuálová stránka programu
mkfifo
– zřízení pojmenované roury