Как да използвате командата xargs в Linux

Трябва да наредите някои команди на Linux заедно, но една от тях не приема въведено по канал? xargs може да вземе изхода от една команда и да го изпрати на друга команда като параметри.

Всички стандартни помощни програми на Linux имат три потока от данни свързани с тях. Те са стандартният входен поток (stdin), стандартният изходен поток (stdout) и стандартният поток за грешки (stderr).

Тези потоци работят с текст. Изпращаме вход (stdin) към команда, използвайки текст, а отговорът (stdout) се записва в прозореца на терминала като текст. Съобщенията за грешки също се записват в прозореца на терминала като текст (stderr).

Една от страхотните характеристики на Linux и Unix-подобните операционни системи е възможността за прехвърляне на изхода stdout от една команда към stdin входа на втора команда. Първата команда не се интересува, че нейният изход не отива в терминален прозорец, а втората команда не се интересува, че нейният вход не идва от клавиатура.

Въпреки че всички команди на Linux имат трите стандартни потока, не всички от тях приемат stdout на друга команда като вход към своя stdin. Това означава, че не можете да насочвате вход към тях.

xargs е команда за изграждане на тръбопроводи за изпълнение, използвайки стандартните потоци от данни. С помощта на xargs можем да накараме команди като echo, rm и mkdir да приемат стандартен вход като аргументи.

Командата xargs

xargs ще приема въведено по канал. Може също да приема вход от файл. xargs използва този вход като параметри за командите, с които сме му казали да работи. Ако не кажем на xargs да работи с конкретна команда, по подразбиране ще използва echo.

Можем да използваме това, за да демонстрираме как xargs винаги ще генерира един ред изход, дори от многоредов вход.

Ако използваме опцията -1 (изброяване на един файл на ред) с ls, получаваме a една колона с имена на файлове.

ls -1 ./*.sh

Това изброява файловете на shell скриптове в текущата директория.

Получаваме една колона, както се очаква. Ако го прекараме през xargs какво получаваме?

ls -1 ./*.sh | xargs

Резултатът се записва в прозореца на терминала като един дълъг поток от текст.

  Как да включите естествените известия за Google Chrome на Linux

Това е тази способност, която позволява на xargs да захранва параметри в други команди.

Използване на xargs с wc

Можем да използваме xargs, за да накараме лесно wc да преброи думи, знаци и редове в множество файлове.

ls *.page | xargs wc

Ето какво се случва:

ls изброява *.page файловете и предава списъка на xargs.
xargs предава имената на файловете на wc.
wc третира имената на файловете, сякаш ги е получил като параметри на командния ред.

Статистиката за всеки файл се показва заедно с общата сума.

Използване на xargs с потвърждение

Можем да използваме опцията -p (интерактивна), за да накараме xargs да ни подкани за потвърждение, че сме щастливи да продължи.

Ако предадем низ от имена на файлове за докосване, чрез xargs, touch ще създайте файловете за нас.

echo 'one two three' | xargs -p touch

Показва се командата, която ще бъде изпълнена и xargs изчаква да отговорим, като напишете „y“ или „Y“, или „n“ или „N“ и натиснете Enter.

Ако просто натиснете Enter, това се третира като „n“. Командата се изпълнява само ако напишете „y“ или „Y“.

Натиснахме „y“ и натиснахме Enter. Можем да използваме ls, за да проверим дали файловете са създадени.

ls one two three

Използване на xargs с множество команди

Можем да използваме множество команди с xargs, като използваме опцията -I (първоначални аргументи).

Тази опция дефинира „низ за замяна“. Където и токенът за заместващия низ се появи в командния ред, стойностите, които са били предоставени на xargs, се вмъкват.

Нека използваме командата дърво, за да разгледаме поддиректориите от текущата директория. Опцията -d (директория) кара дървото да игнорира файлове и да докладва само за директории.

tree -d

Има една поддиректория, наречена „изображения“.

Във файл, наречен “directories.txt”, имаме имената на някои директории, които искаме да създадем. Можем да разгледаме съдържанието му с помощта на cat.

cat directories.txt

Ще използваме това като входни данни за xargs. Командата, която ще изпълним е следната:

cat directories.txt | xargs -I % sh -c 'echo %; mkdir %'

Това се разпада така:

cat directories.txt |: Това изтласква съдържанието на файла directorories.txt (всички нови имена на директории) в xargs.
xargs -I %: Това дефинира „заместен низ“ с токена „%“.
sh -c: Това стартира нова подчерупка. -c (командата) казва на обвивката да чете команди от командния ред.
‘ехо %; mkdir %’: всеки от токените „%“ ще бъде заменен от имената на директории, които се предават от xargs. Командата echo ще отпечата името на директорията; командата mkdir ще създаде директорията.

  Как да инсталирате Slackware Linux

Директориите са изброени една по една.

Можем да използваме дървото още веднъж, за да проверим дали директориите са създадени.

tree -d

Копиране на файлове на множество места

Можем да използваме xargs, за да ни позволи да копираме файлове на множество места с една команда.

Ще прехвърлим имената на две директории в xargs като входни параметри. Ще кажем на xargs да предава само един от тези параметри в даден момент на командата, с която работи.

В този случай командата е cp. Така че ефектът е да извикате cp два пъти, всеки път с една от двете директории като параметър на командния ред. Параметърът xargs, който позволява това да се случи, е опцията -n (макс. брой). Ще настроим това да бъде едно.

Ние също така използваме опцията -v (подробно) с cp, така че да отчита какво се случва.

echo ~/Backups/ ~/Documents/page-files/ | xargs -n 1 cp -v ./*.page

Файловете се копират в двете директории, една по една. cp отчита всяко действие за копиране на файл, за да можем да видим как се извършва.

Изтриване на файлове във вложени директории

Ако имената на файлове имат интервали и странни знаци в тях — като знаци за нов ред — xargs няма да могат да ги интерпретират правилно. Можем да преодолеем този проблем, като използваме опцията -0 (нулев терминатор). Това казва на xargs да използва символа null като краен разделител за имена на файлове.

Ще използваме find в този пример. find има своя собствена опция за справяне с пробелите и странни знаци в имената на файлове. Това е опцията -print0 (пълно име, нулев знак).

find . -name "*.png" -type f -print0 | xargs -0 rm -v -rf "{}"

Това се разпада така:

намирам . -name “*.png”: find ще търси от текущата директория “.” за обекти с имена, които съответстват на „*.png“, които са файлове (тип -f).
-print0: имената ще бъдат завършени с нулев знак, а интервалите и странните знаци ще бъдат обслужени.
xargs -0: xargs също ще счита имената на файлове за завършващи с нула и интервалите и странните знаци няма да създават проблеми.
rm -v -rf “{}”: rm ще бъде многословен и ще докладва какво се случва (-v). Той ще бъде рекурсивен (-r) и ще преглежда вложени поддиректории и ще премахне файловете без подканване (-f). „{}“ се заменя с всяко име на файл.

  Как да създадете страница на човек в Linux

намирам .  -име

Всички поддиректории се търсят и файловете, които съответстват на шаблона за търсене, се изтриват.

Премахване на вложени директории

Да кажем, че искаме да премахнем набор от вложени поддиректории. дървото ще ни позволи да ги видим.

tree -d

find . -name "level_one" -type d printo | xargs -o rm -v -rf "{}"

Тази команда ще използва find за рекурсивно търсене в текущата директория. Целта за търсене е директория, наречена „level_one“. Имената на директории се предават през xargs към rm.

намирам .  -име

Единствените значителни промени между тази команда и предишната команда са, че терминът за търсене е името на най-горната директория, а -type d казва find да търси директории, а не файлове.

Името на всяка директория се отпечатва, когато бъде премахната. Можем да проверим с дърво:

tree -d

Всички вложени поддиректории се изтриват.

Изтриване на всички файлове, с изключение на един тип файл

Можем да използваме find, xargs и rm, за да изтрием всички файлове, освен един тип, който искаме да запазим. Това е леко противоинтуитивно, но ние предоставяме името на файловия тип, който искаме да запазим, а не името на тези, които искаме да изтрием.

Опцията -not казва на find да върне имената на файловете, които не съответстват на шаблона за търсене. Използваме опцията -I (първоначални аргументи) с xargs още веднъж. Този път символът за заместващ низ, който дефинираме, е „{}“. Това ще се държи точно по същия начин като маркера за заместващ низ, който генерирахме по-рано, който се оказа „%“.

find . -type f -not - name "*.sh" -print0 | xargs -0 -I {} rm -v {}

намирам .  -type f -not - име

Можем да проверим с ls. Единствените файлове, останали в директорията, са тези, които съответстват на модела за търсене „*.sh“.

ls -l

Създаване на архивен файл с Xargs

Можем да използваме find, за да търсим файлове и да ги предаваме през xargs в tar, за да създадем архивен файл.

Ще търсим в текущата директория. Моделът за търсене е „*.page“, така че ще търсим „.page“ файлове.

find ./ - name "*.page" -type f -print0 | xargs -0 -tar -cvzf page_files.tar.gz

намери ./ - име

Файловете са изброени според очакванията, тъй като архивният файл е създаден.

Посредникът на данни

Понякога имате нужда от малко скеле, когато подреждате нещата заедно. xargs преодолява пропастта между командите, които могат да изпомпват информация и командите, които не са вградени, за да я приемат.

И xargs, и find имат огромен брой опции. Насърчаваме ви да разгледате техните man страници, за да научите повече.