Как использовать команду xargs в Linux
Нужно объединить несколько команд Linux, но одна из них не принимает ввод по конвейеру? xargs
может принимать выходные данные одной команды и отправлять их другой команде в качестве параметров.
Все стандартные утилиты Linux имеют три связанных с ними потока данных. Это стандартный поток ввода (stdin), стандартный поток вывода (stdout) и стандартный поток ошибок (stderr).
Эти потоки работают с текстом. Мы отправляем ввод (stdin) в команду с помощью текста, а ответ (stdout) записывается в окно терминала в виде текста. Сообщения об ошибках также записываются в окно терминала в виде текста (stderr).
Одной из замечательных особенностей Linux и Unix-подобных операционных систем является возможность направлять вывод stdout одной команды на ввод stdin второй команды. Первой команде все равно, что ее вывод не идет в окно терминала, а второй команде все равно, что ее ввод не идет с клавиатуры.
Хотя все команды Linux имеют три стандартных потока, не все они принимают стандартный вывод другой команды в качестве входных данных для своего стандартного ввода. Это означает, что вы не можете передать им входные данные.
xargs
— это команда для построения конвейеров выполнения с использованием стандартных потоков данных. С помощью xargs
мы можем сделать так, чтобы такие команды, как echo
, rm
и mkdir
, принимали стандартный ввод в качестве аргументов.
Команда xargs
xargs
будет принимать ввод по конвейеру. Он также может принимать ввод из файла. xargs
использует эти входные данные в качестве параметров для команд, с которыми мы сказали ему работать. Если мы не укажем xargs
работать с определенной командой, по умолчанию будет использоваться echo
.
Мы можем использовать это, чтобы продемонстрировать, как xargs
всегда будет генерировать одну строку вывода, даже из многострочного ввода.
Если мы используем параметр -1
(указать один файл в строке) с ls
, мы получим один столбец имен файлов.
ls -1 ./*.sh
Здесь перечислены файлы сценариев оболочки в текущем каталоге.
Мы получаем один столбец, как и ожидалось. Если мы пропустим его через xargs
, что мы получим?
ls -1 ./*.sh | xargs
Вывод записывается в окно терминала в виде одного длинного потока текста.
Именно эта возможность позволяет xargs
передавать параметры другим командам.
Использование xargs с wc
Мы можем использовать xargs
, чтобы wc
легко подсчитывал слова, символы и строки в нескольких файлах.
ls *.page | xargs wc
Вот что происходит:
ls
выводит список файлов *.page и передает этот список вxargs
.xargs
передает имена файлов вwc
.wc
обрабатывает имена файлов так, как если бы они были получены в качестве параметров командной строки.
Статистика для каждого файла отображается вместе с общим итогом.
Использование xargs с подтверждением
Мы можем использовать параметр -p
(интерактивный), чтобы xargs
запрашивал у нас подтверждение того, что мы согласны на его продолжение.
Если мы передадим строку имен файлов в touch
через 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
.
Давайте воспользуемся командой tree
для просмотра подкаталогов из текущего каталога. Параметр -d
(каталог) заставляет tree
игнорировать файлы и сообщать только о каталогах.
tree -d
Существует единственный подкаталог под названием «images».
В файле с именем «directories.txt» у нас есть имена некоторых каталогов, которые мы хотим создать. Мы можем просмотреть его содержимое с помощью cat
.
cat directories.txt
Мы собираемся использовать это как входные данные для xargs
. Команда, которую мы собираемся выполнить, такова:
cat directories.txt | xargs -I % sh -c 'echo %; mkdir %'
Это ломается следующим образом:
- cat directory.txt |: содержимое файла directorys.txt (все новые имена каталогов) помещается в
xargs
. - xargs -I %: определяет «заменить строку» токеном «%».
- sh -c: запускает новую подоболочку.
-c
(команда) указывает оболочке читать команды из командной строки. - ‘эхо %; mkdir %’: каждый из токенов «%» будет заменен именами каталогов, переданными с помощью
xargs
. Командаecho
напечатает имя каталога; командаmkdir
создаст каталог.
Каталоги перечислены один за другим.
Мы можем использовать tree
еще раз, чтобы убедиться, что каталоги были созданы.
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
использовать нулевой символ в качестве последнего разделителя для имен файлов.
В этом примере мы будем использовать find
. find
имеет собственный параметр для работы с пробелами и странными символами в именах файлов. Это опция -print0
(полное имя, нулевой символ).
find . -name "*.png" -type f -print0 | xargs -0 rm -v -rf "{}"
Это ломается следующим образом:
- найти . -name «*.png»:
find
будет искать в текущем каталоге «.» для объектов с именами, соответствующими «*.png», которые являются файлами (type -f
). - -print0: имена будут заканчиваться нулевым символом, а пробелы и странные символы будут учитываться.
- xargs -0: xargs также будет считать имена файлов заканчивающимися нулем, а пробелы и странные символы не вызовут проблем.
- rm -v -rf “{}”: rm будет подробным и сообщит о том, что происходит (
-v
). Он будет рекурсивным (-r) и будет просматривать вложенные подкаталоги и удалять файлы без запроса (-f
). «{}» заменяется каждым именем файла.
Поиск выполняется во всех подкаталогах, и файлы, соответствующие шаблону поиска, удаляются.
Удаление вложенных каталогов
Допустим, мы хотим удалить набор вложенных подкаталогов. tree
позволит нам их увидеть.
tree -d
find . -name "level_one" -type d printo | xargs -o rm -v -rf "{}"
Эта команда будет использовать find для рекурсивного поиска в текущем каталоге. Целью поиска является каталог с именем «level_one». Имена каталогов передаются через xargs
в rm
.
Единственные существенные различия между этой командой и предыдущей командой заключаются в том, что термин поиска — это имя самого верхнего каталога, а -type d
указывает find
искать каталоги, а не файлы.
Имя каждого каталога печатается по мере его удаления. Мы можем проверить с помощью tree
:
tree -d
Все вложенные подкаталоги удаляются.
Удаление всех файлов, кроме файлов одного типа
Мы можем использовать find
, xargs
и rm
, чтобы удалить все файлы, кроме одного типа, который мы хотим сохранить. Это немного нелогично, но мы указываем имя типа файла, который хотим сохранить, а не имя файла, который хотим удалить.
Параметр -not
сообщает find
, чтобы он возвращал имена файлов, которые не соответствуют шаблону поиска. Мы снова используем параметр -I
(начальные аргументы) с xargs
. На этот раз токен замены строки, который мы определяем, — «{}». Это будет вести себя точно так же, как токен замены строки, который мы создали ранее, который оказался «%».
find . -type f -not - name "*.sh" -print0 | xargs -0 -I {} rm -v {}
Мы можем проверить с помощью 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
имеют огромное количество параметров. Вам предлагается проверить их справочные страницы, чтобы узнать больше.
Linux Commands | ||
Files | tar · pv · cat · tac · chmod · grep · diff · sed · ar · man · pushd · popd · fsck · testdisk · seq · fd · pandoc · cd · $PATH · awk · join · jq · fold · uniq · journalctl · tail · stat · ls · fstab · echo · less · chgrp · chown · rev · look · strings · type · rename · zip · unzip · mount · umount · install · fdisk · mkfs · rm · rmdir · rsync · df · gpg · vi · nano · mkdir · du · ln · patch · convert · rclone · shred · srm · scp · gzip · chattr · cut · find · umask · wc | |
Processes | alias · screen · top · nice · renice · progress · strace · systemd · tmux · chsh · history · at · batch · free · which · dmesg · chfn · usermod · ps · chroot · xargs · tty · pinky · lsof · vmstat · timeout · wall · yes · kill · sleep · sudo · su · time · groupadd · usermod · groups · lshw · shutdown · reboot · halt · poweroff · passwd · lscpu · crontab · date · bg · fg · pidof · nohup · pmap | |
Networking | netstat · ping · traceroute · ip · ss · whois · fail2ban · bmon · dig · finger · nmap · ftp · curl · wget · who · whoami · w · iptables · ssh-keygen · ufw · arping · firewalld |
RELATED: Best Linux Laptops for Developers and Enthusiasts