Нужно объединить некоторые команды Linux вместе, но одна из них не принимает ввод по каналу? xargs
может взять вывод одной команды и отправить ее другой команде в качестве параметров.
У всех стандартных утилит Linux есть три потока данных, связанных с ними. Это стандартный поток ввода (stdin), стандартный поток вывода (stdout) и стандартный поток ошибок (stderr).
Эти потоки работают с текстом. Мы отправляем ввод (stdin) команде, используя текст, и ответ (stdout) записывается в окно терминала в виде текста. Сообщения об ошибках также записываются в окно терминала в виде текста (stderr).
Одной из замечательных особенностей Linux и Unix-подобных операционных систем является возможность передавать вывод stdout одной команды на ввод stdin второй команды. Первая команда не заботится о том, что ее вывод не идет в окно терминала, а вторая команда не заботится о том, что ее ввод не поступает с клавиатуры.
Хотя все команды Linux имеют три стандартных потока, не все из них принимают стандартный вывод другой команды в качестве ввода в свой стандартный ввод. Это означает, что вы не можете направить на них данные.
xargs
— это команда для построения конвейеров выполнения с использованием стандартных потоков данных. Используя xargs
мы можем заставить команды, такие как echo
, rm
и mkdir
принимать стандартный ввод в качестве аргументов.
Команда Xargs
xargs
примет ввод по xargs
. Он также может принимать входные данные из файла. xargs
использует этот ввод в качестве параметров для команд, с которыми мы говорили работать. Если мы не скажем xargs
работать с определенной командой, по умолчанию будет использоваться echo
.
Мы можем использовать это, чтобы продемонстрировать, как xargs
всегда генерирует одну строку вывода, даже из многострочного ввода.
Если мы используем опцию -1
(перечислить один файл на строку) с ls
, мы получим один столбец имен файлов .
ls -1 ./*.sh
Здесь перечислены файлы сценариев оболочки в текущем каталоге.
Мы получаем один столбец, как и ожидалось. Если мы отправим это через xargs
что мы получим?
ls -1 ./*.sh | xargs
Вывод записывается в окно терминала как один длинный поток текста.
Именно эта возможность позволяет xargs
параметры в другие команды.
Использование xargs с wc
Мы можем использовать xargs
для простого подсчета слов, символов и строк в нескольких файлах.
ls * .page | xargs wc
Вот что происходит:
-
ls
перечисляет файлы * .page и передает список вxargs
. -
xargs
передает имена файлов вwc
. -
wc
обрабатывает имена файлов так, как если бы они получили их как параметры командной строки.
Статистика для каждого файла отображается вместе с общей суммой.
Использование xargs с подтверждением
Мы можем использовать опцию -p
(интерактивный), чтобы xargs
запрашивал у нас подтверждение того, что мы рады, что он продолжается.
Если мы передадим строку имен файлов touch
через xargs
, touch
создаст файлы для нас.
эхо "один два три" | xargs -p touch
Команда, которая должна быть выполнена, отображается, и xargs
ждет от нас ответа, набрав «y» или «Y», или «n» или «N», и нажав Enter.
Если вы просто нажмете Enter, он будет считаться «n». Команда выполняется только в том случае, если вы вводите «y» или «Y».
Мы нажали «y» и нажали Enter. Мы можем использовать ls
чтобы проверить, что файлы были созданы.
один раз два три
Использование xargs с несколькими командами
Мы можем использовать несколько команд с xargs
, используя опцию -I
(начальные аргументы).
Эта опция определяет «строку замены». Везде, где токен для строки замены появляется в командной строке, вставляются значения, которые были xargs
в xargs
.
Давайте используем команду tree
для просмотра подкаталогов из текущего каталога. Опция -d
(directory) заставляет tree
игнорировать файлы и сообщать только о каталогах.
дерево-г
Существует один подкаталог, который называется «images».
В файле с именем «directoryies.txt» у нас есть имена некоторых каталогов, которые мы хотим создать. Мы можем посмотреть на его содержимое, используя cat
.
cat directoryies.txt
Мы собираемся использовать это в качестве входных данных для xargs
. Команда, к которой мы собираемся, это:
cat directoryies.txt | xargs -I% sh -c 'echo%; mkdir% '
Это ломается так:
- cat directoryies.txt | : Это помещает содержимое файла directrories.txt (все новые имена каталогов) в
xargs
. - xargs -I% : это определяет «replace-string» с токеном «%».
- sh -c : это запускает новый подоболочек.
-c
(команда) говорит оболочке читать команды из командной строки. - ‘эхо%; mkdir% ‘ : каждый из токенов «%» будет заменен на имена каталогов, которые передаются
xargs
. Командаecho
напечатает имя каталога; командаmkdir
создаст каталог.
Каталоги перечислены один за другим.
Мы можем использовать tree
еще раз, чтобы убедиться, что каталоги были созданы.
дерево-г
Копирование файлов в несколько мест
Мы можем использовать xargs
чтобы с помощью одной команды скопировать файлы в несколько мест.
Мы собираемся xargs
имена двух каталогов в xargs
в качестве входных параметров. Мы скажем xargs
передавать только один из этих параметров за раз команде, с которой он работает.
В этом случае команда является cp
. Таким образом, эффект заключается в вызове cp
дважды, каждый раз с одним из двух каталогов в качестве параметра командной строки. Параметр xargs
который позволяет это сделать, является опцией -n
(максимальное число). Мы собираемся установить это, чтобы быть одним.
Мы также используем параметр -v
(подробный) с cp
чтобы он сообщал о происходящем.
echo ~ / Резервные копии / ~ / Документы / Страничные файлы / | xargs -n 1 cp -v ./*.page
Файлы копируются в две директории, по одной директории за раз. cp
сообщает о каждом действии копирования файла, чтобы мы могли видеть его выполнение.
Удаление файлов во вложенных каталогах
Если в именах файлов есть пробелы и странные символы, такие как символы новой строки, xargs
не сможет правильно их интерпретировать. Мы можем решить эту проблему, используя опцию -0 (нулевой терминатор). Это говорит xargs
использовать нулевой символ в качестве конечного разделителя для имен файлов.
Мы собираемся использовать find
в этом примере. find
имеет собственную опцию для работы с пробелами и странными символами в именах файлов. Это -print0
(полное имя, нулевой символ).
находить . -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
позволит нам увидеть их.
дерево-г
находить . имя "level_one" -тип d printo | xargs -o rm -v -rf "{}"
Эта команда будет использовать поиск для рекурсивного поиска в текущем каталоге. Целью поиска является каталог с именем level_one. Имена каталогов передаются через xargs
в rm
.
Единственные существенные изменения между этой командой и предыдущей командой заключаются в том, что поисковый термин — это имя самого верхнего каталога, а -type d
указывает find
искать каталоги, а не файлы.
Название каждого каталога печатается по мере удаления. Мы можем проверить с tree
:
дерево-г
Все вложенные подкаталоги будут удалены.
Удаление всех файлов, кроме одного типа
Мы можем использовать find
, xargs
и rm
чтобы удалить все файлы, кроме одного типа, который мы хотим сохранить. Это немного нелогично, но мы предоставляем имя типа файла, который мы хотим сохранить , а не имя тех, которые мы хотим удалить.
Опция -not
указывает find
возвращать имена файлов, которые не соответствуют шаблону поиска. Мы снова используем опцию -I
(исходные аргументы) с xargs
. На этот раз мы определяем токен замещающей строки «{}». Это будет вести себя точно так же, как токен замещающей строки, сгенерированный нами ранее, который оказался «%».
находить . -type f -not - имя "* .sh" -print0 | xargs -0 -I {} rm -v {}
Мы можем проверить с ls
. В каталоге остались только файлы, соответствующие шаблону поиска «* .sh».
ls -l
Создание архивного файла с помощью Xargs
Мы можем использовать find
для поиска файлов и передачи их через xargs
в tar
, чтобы создать архивный файл.
Мы собираемся искать в текущем каталоге. Шаблон поиска — «* .page», поэтому мы будем искать файлы «.page».
найти ./ - имя "* .page" -type f -print0 | xargs -0 -tar -cvzf page_files.tar.gz
Файлы отображаются в ожидаемом порядке, поскольку создается файл архива.
Посредник данных
Иногда вам нужно немного строительных лесов, когда вы складываете вещи вместе. xargs
разрыв между командами, которые могут откачивать информацию, и командами, которые не созданы, чтобы принять ее.
Оба xargs
и find
имеют огромное количество опций. Вам предлагается проверить их справочные страницы, чтобы узнать больше.