Potřebujete spojit některé linuxové příkazy dohromady, ale jeden z nich nepřijímá vstup z potrubí? xargs může převzít výstup z jednoho příkazu a odeslat jej jinému příkazu jako parametry.
Všechny standardní linuxové nástroje mají tři datové toky s nimi spojené. Jsou to standardní vstupní proud (stdin), standardní výstupní proud (stdout) a standardní chybový proud (stderr).
Tyto proudy pracují s textem. Vstup (stdin) odešleme příkazu pomocí textu a odpověď (stdout) se zapíše do okna terminálu jako text. Chybové zprávy se také zapisují do okna terminálu jako text (stderr).
Jednou ze skvělých vlastností Linuxu a operačních systémů podobných Unixu je schopnost propojit výstup stdout z jednoho příkazu do vstupu stdin druhého příkazu. Prvnímu příkazu je jedno, že jeho výstup nejde do okna terminálu, a druhému příkazu je jedno, že jeho vstup nepřichází z klávesnice.
Ačkoli všechny linuxové příkazy mají tři standardní proudy, ne všechny přijímají stdout jiného příkazu jako vstup do jejich stdin. To znamená, že do nich nemůžete zadávat vstup.
xargs je příkaz pro vytváření prováděcích kanálů pomocí standardních datových toků. Pomocí xargs můžeme zajistit, aby příkazy jako echo, rm a mkdir přijímaly standardní vstup jako argumenty.
Table of Contents
Příkaz xargs
xargs přijme vstup z potrubí. Může také přijímat vstup ze souboru. xargs používá tento vstup jako parametry pro příkazy, se kterými jsme mu řekli, aby pracoval. Pokud neřekneme xargs, aby pracoval s konkrétním příkazem, standardně použije echo.
Můžeme to použít k demonstraci toho, jak xargs vždy generuje jeden řádek výstupu, dokonce i z víceřádkového vstupu.
Pokud použijeme volbu -1 (vypsat jeden soubor na řádek) s ls, dostaneme a jeden sloupec názvů souborů.
ls -1 ./*.sh
Zde jsou uvedeny soubory skriptů shellu v aktuálním adresáři.
Podle očekávání dostaneme jeden sloupec. Když to propojíme xargs, co dostaneme?
ls -1 ./*.sh | xargs
Výstup je zapsán do okna terminálu jako jeden dlouhý proud textu.
Je to tato schopnost, díky které xargs vkládá parametry do jiných příkazů.
Použití xargs s wc
Můžeme použít xargs, abychom mohli snadno spočítat wc slova, znaky a řádky ve více souborech.
ls *.page | xargs wc
Toto se stane:
ls vypíše soubory *.page a předá seznam xargs.
xargs předává názvy souborů do wc.
wc zachází s názvy souborů, jako by je přijal jako parametry příkazového řádku.
Statistiky pro každý soubor se zobrazí společně s celkovým součtem.
Použití xargs s potvrzením
Můžeme použít volbu -p (interaktivní), aby nás xargs vyzval k potvrzení, že jsme rádi, že bude pokračovat.
Pokud předáme řetězec názvů souborů, které se mají dotknout, pomocí xargs, dotyk bude vytvořit soubory pro nás.
echo 'one two three' | xargs -p touch
Zobrazí se příkaz, který se má provést, a xargs čeká na naši odpověď zadáním „y“ nebo „Y“ nebo „n“ nebo „N“ a stisknutím klávesy Enter.
Pokud pouze stisknete Enter, bude to považováno za „n“. Příkaz se provede, pouze pokud zadáte „y“ nebo „Y“.
Stiskli jsme „y“ a stiskli Enter. Můžeme použít ls ke kontrole, zda byly soubory vytvořeny.
ls one two three
Použití xargs s více příkazy
Můžeme použít více příkazů s xargs pomocí volby -I (počáteční argumenty).
Tato možnost definuje „replace-string“. Kdekoli se na příkazovém řádku objeví token pro nahrazený řetězec, jsou vloženy hodnoty, které byly dodány do xargs.
Pomocí příkazu tree se podíváme na podadresáře z aktuálního adresáře. Volba -d (adresář) způsobí, že strom bude ignorovat soubory a bude hlásit pouze adresáře.
tree -d
Existuje jeden podadresář s názvem „images“.
V souboru s názvem „directories.txt“ máme názvy některých adresářů, které si přejeme vytvořit. Na jeho obsah se můžeme podívat pomocí cat.
cat directories.txt
Použijeme to jako vstupní data pro xargs. Příkaz, ke kterému se chystáme, je tento:
cat directories.txt | xargs -I % sh -c 'echo %; mkdir %'
Toto se rozpadá takto:
cat directories.txt |: Toto vloží obsah souboru directories.txt (všechny nové názvy adresářů) do xargs.
xargs -I %: Definuje „nahradit řetězec“ tokenem „%“.
sh -c: Toto spustí nový subshell. -c (příkaz) říká shellu, aby četl příkazy z příkazového řádku.
‚echo %; mkdir %‘: každý z tokenů „%“ bude nahrazen názvy adresářů, které předají xargs. Příkaz echo vypíše název adresáře; příkaz mkdir vytvoří adresář.
Adresáře jsou uvedeny jeden po druhém.
Můžeme použít strom ještě jednou, abychom ověřili, že adresáře byly vytvořeny.
tree -d
Kopírování souborů do více umístění
Můžeme použít xargs, abychom mohli kopírovat soubory na více míst pomocí jediného příkazu.
Jména dvou adresářů převedeme do xargs jako vstupní parametry. Řekneme xargs, aby příkazu, se kterým pracuje, předal vždy pouze jeden z těchto parametrů.
V tomto případě je příkaz cp. Výsledkem je tedy volání cp dvakrát, pokaždé s jedním ze dvou adresářů jako parametrem příkazového řádku. Parametr xargs, který to umožňuje, je volba -n (maximální počet). Nastavíme to na jeden.
Také používáme volbu -v (verbózní) s cp, aby hlásil, co se děje.
echo ~/Backups/ ~/Documents/page-files/ | xargs -n 1 cp -v ./*.page
Soubory jsou zkopírovány do dvou adresářů, jeden adresář po druhém. cp hlásí každou akci kopírování souboru, abychom viděli, jak se odehrává.
Mazání souborů ve vnořených adresářích
Pokud názvy souborů obsahují mezery a podivné znaky – například znaky nového řádku – xargs je nebude schopen správně interpretovat. Tento problém můžeme překonat použitím volby -0 (null terminátor). To říká xargs, aby použil znak null jako konečný oddělovač pro názvy souborů.
V tomto příkladu použijeme find. find má svou vlastní volbu řešení mezer a podivné znaky v názvech souborů. Je to volba -print0 (celé jméno, znak null).
find . -name "*.png" -type f -print0 | xargs -0 rm -v -rf "{}"
Toto se rozpadá takto:
najít -name „*.png“: find bude hledat v aktuálním adresáři „.“ pro objekty s názvy, které odpovídají „*.png“, což jsou soubory (typ -f).
-print0: jména budou ukončena znakem null a bude postaráno o mezery a podivné znaky.
xargs -0: xargs bude také považovat názvy souborů za ukončené nulou a mezery a podivné znaky nezpůsobí problémy.
rm -v -rf „{}“: rm bude podrobný a bude hlásit, co se děje (-v). Bude rekurzivní (-r) a bude procházet vnořené podadresáře a odstraní soubory bez výzvy (-f). „{}“ je nahrazeno každým souborem.
Prohledají se všechny podadresáře a smažou se soubory, které odpovídají vyhledávacímu vzoru.
Odebírání vnořených adresářů
Řekněme, že chceme odstranit sadu vnořených podadresářů. strom nám je umožní vidět.
tree -d
find . -name "level_one" -type d printo | xargs -o rm -v -rf "{}"
Tento příkaz použije find k rekurzivnímu vyhledávání v aktuálním adresáři. Cílem vyhledávání je adresář nazvaný „level_one“. Jména adresářů jsou předávána přes xargs do rm.
Jedinými významnými změnami mezi tímto příkazem a předchozím příkazem je, že hledaný výraz je název nejvyššího adresáře a -type d říká, že find má hledat adresáře, nikoli soubory.
Název každého adresáře se vytiskne po jeho odstranění. Můžeme zkontrolovat pomocí stromu:
tree -d
Všechny vnořené podadresáře budou odstraněny.
Smazání všech souborů, kromě jednoho typu souboru
Můžeme použít find, xargs a rm k odstranění všech souborů kromě jednoho typu, který chceme zachovat. Je to trochu neintuitivní, ale poskytujeme název typu souboru, který si přejeme zachovat, nikoli názvy souborů, které chceme smazat.
Volba -not říká find, aby vrátila názvy souborů, které neodpovídají vyhledávacímu vzoru. Znovu používáme volbu -I (počáteční argumenty) s xargs. Tentokrát je token náhradního řetězce, který definujeme, „{}“. To se bude chovat úplně stejně jako token nahrazujícího řetězce, který jsme vygenerovali dříve, což bylo „%“.
find . -type f -not - name "*.sh" -print0 | xargs -0 -I {} rm -v {}
Můžeme to zkontrolovat s ls. V adresáři zůstaly pouze soubory, které odpovídaly vyhledávacímu vzoru „*.sh“.
ls -l
Vytvoření archivního souboru pomocí Xargs
Můžeme použít find k vyhledání souborů a jejich předání přes xargs do tar, k vytvoření archivního souboru.
Budeme hledat v aktuálním adresáři. Vzor vyhledávání je „*.page“, takže budeme hledat soubory „.page“.
find ./ - name "*.page" -type f -print0 | xargs -0 -tar -cvzf page_files.tar.gz
Soubory jsou uvedeny podle očekávání při vytváření archivního souboru.
Zprostředkovatel dat
Někdy potřebujete malé lešení, když skládáte věci dohromady. xargs překlenuje propast mezi příkazy, které mohou čerpat informace, a příkazy, které nejsou vytvořeny tak, aby je přijaly.
Jak xarg, tak find mají obrovské množství možností. Doporučujeme vám podívat se na jejich manuálové stránky, kde se dozvíte více.