Pravděpodobně již znáte vstup/výstup a přesměrování potrubí v Linuxu.
Dovolte mi, abych vám řekl o podobné, ale pokročilé funkci zvané substituce procesů.
Najdete zde dva druhy syntaxe pro substituci procesů:
<(commands)
nebo
>(commands)
Dovolte mi jít trochu podrobněji.
Náhrada procesu Bash
Zjistíte, že substituci procesu lze použít podobně jako přesměrování STDOUT nebo STDIN.
Pomocí <(commands)
operátor, vyčtete ze suplování. To znamená, že commands
je nastaven tak, aby jej používal jako stdout
.
Například následující příkaz používá výstup ls *sh
:
wc -l <(ls *sh)
To je ekvivalentní:
ls *sh | wc -l
Pomocí >(commands)
operátora, napíšete do supl. To znamená, že commands
je nastaven tak, aby jej používal jako stdin
.
Jinými slovy, když máte příkaz, který vydává výstup do souboru, ale chcete, aby zapisoval do jiného příkazu místo do souboru.
Zde je příklad, který by měl věci trochu objasnit:
tar -cf >(ssh remote_server tar xf -) .
Uvědomujete si, co to dělá? To je správně. Právě jste přenesli veškerý obsah aktuálního adresáře na vzdálený server. Archivní soubor je vytvořen za chodu a je extrahován na serveru.
Abych byl upřímný, >(...)
operátor je méně častý. Zjistíte, že <(...)
lze používat častěji.
Jaká je tedy výhoda substituce procesu, pokud funguje jako běžné přesměrování vstupu a výstupu?
Sílu a užitečnost substituce bash procesem si uvědomíte, když budete mít více příkazových kanálů, které lze spojit do jediného příkazu.
Výhoda substituce procesu bash
Nejzřetelnějším a nejčastějším využitím procesní substituce je porovnání výstupů dvou programů. Dovolte mi, abych vám to ukázal na praktickém příkladu.
Řekněme, že máte v adresáři nějaké soubory programu C a jejich odpovídající objektové soubory (soubor .out) se stejným názvem.
ls *
aa.c aa.out bb.c bb.out cc.c cc.out ...
Zde je váš cíl. Chcete zkontrolovat, zda každý soubor C má svůj odpovídající výstupní soubor se stejným názvem jako soubor C nebo ne.
Typickým postupem by bylo vypsat seznam souborů filtrovaných podle přípony a poté pomocí příkazu cut s oddělovačem .(tečka) extrahovat název souboru bez přípony:
ls *.c | cut -d. -f1
aa
bb
cc
dd
Typickým přístupem by bylo uložit výstup souborů *.c a *.out do dočasných souborů a poté tyto soubory porovnat s příkazem diff. Mám pravdu?
ls *.c | cut -d. -f1 > c.txt
ls *.out | cut -d. -f1 > out.txt
diff c.txt out.txt
rm c.txt out.txt
Můžete použít adresář /tmp k vytvoření dočasných souborů, ale stále máte tři řádky příkazů.
Můžete krásně použít substituci procesu k nahrazení všeho výše uvedeného jediným příkazem bez vytváření dočasných souborů:
diff <(ls *.c | cut -d. -f1) <(ls *.out | cut -d. -f1)
Nepotřebovali jste zde vytvářet žádné dočasné soubory a to je to hlavní. Zde je můj tip, kdy byste měli použít substituci procesů.
Kdykoli si myslíte, že k něčemu potřebujete dočasný soubor, zvažte, zda lze použít náhradu procesu.
Nahrazení procesu je funkce bash a může nebo nemusí fungovat s jiným shellem.
Doufám, že v budoucnu vyzkoušíte a použijete substituci procesů. Jak vidíte, je to docela užitečné. Uvítám vaše dotazy a návrhy.