Jump to content

xargs

xargs
Разработчик(и) Различные с открытым исходным кодом и коммерческие разработчики разработчики
Операционная система Unix , Unix-подобные , Plan 9 , IBM i
Платформа Кросс-платформенный
Тип Команда

xargs сокращение расширенные аргументы « » от ( [1] ) — это команда в Unix и большинстве Unix-подобных операционных систем, используемая для создания и выполнения команд из стандартного ввода . Он преобразует входные данные стандартного ввода в аргументы команды.

Некоторые команды, такие как grep и awk может принимать входные данные либо в виде аргументов командной строки, либо из стандартного ввода. Однако другие, такие как cp и echo может принимать входные данные только в качестве аргументов, поэтому xargs необходим .

Порт более старой версии GNU. xargs доступен для Microsoft Windows как часть UnxUtils коллекции , состоящей из собственных Win32- портов распространенных GNU Unix-подобных утилит. [2] Переписывание с нуля под названием wargs является частью TextTools с открытым исходным кодом. [3] проект. Команда xargs также была перенесена в операционную систему IBM i . [4]

Одним из вариантов использования команды xargs является удаление списка файлов с помощью команды rm . Системы POSIX имеют ARG_MAX для максимальной общей длины командной строки, [5] [6] поэтому команда может завершиться неудачно с сообщением об ошибке «Список аргументов слишком длинный» (это означает, что предел системного вызова exec на длину командной строки был превышен): rm /path/* или rm $(find /path -type f). (Последний вызов неверен, так как он может расширить globs в выходных данных.)

Это можно переписать с помощью xargs команда, чтобы разбить список аргументов на подсписки, достаточно маленькие, чтобы их можно было принять:

$ find /path -type f -print | xargs rm

В приведенном выше примере find Утилита подает входные данные xargs с длинным списком имен файлов. xargs затем разбивает этот список на подсписки и вызывает rm один раз для каждого подсписка.

Некоторые реализации xargs также можно использовать для распараллеливания операций с -P maxprocs аргумент, чтобы указать, сколько параллельных процессов следует использовать для выполнения команд над списками входных аргументов. Однако выходные потоки могут быть не синхронизированы. Это можно преодолеть, используя --output file аргумент, где это возможно, а затем объединение результатов после обработки. В следующем примере 24 процесса ставятся в очередь и ждут завершения каждого, прежде чем запускать другой.

$ find /path -name '*.foo' | xargs -P 24 -I '{}' /cpu/bound/process '{}' -o '{}'.out

xargs часто охватывает ту же функциональность, что и функция подстановки команд во многих оболочках , обозначаемая обратными кавычками ( `...` или $(...)). xargs также является хорошим помощником для команд, выводящих длинные списки файлов, таких как find, locate и grep, но только если использовать -0 (или эквивалентно --null), с xargs без -0 плохо обрабатывает имена файлов, содержащие ', " и космос. GNU Parallel — аналогичный инструмент, который обеспечивает лучшую совместимость с find , locate и grep, когда имена файлов могут содержать ', "и пробел (новая строка по-прежнему требует -0).

Размещение аргументов

[ редактировать ]

-I вариант: один аргумент

[ редактировать ]

Команда xargs предлагает опции для вставки перечисленных аргументов в какую-либо позицию, отличную от конца командной строки. -I Опция xargs принимает строку, которая будет заменена предоставленным вводом перед выполнением команды. Общий выбор – это %.

$ mkdir ~/backups
$ find /path -type f -name '*~' -print0 | xargs -0 -I % cp -a % ~/backups

Заменяемая строка может появляться в командной части несколько раз. С использованием -I вообще ограничивает количество используемых каждый раз строк до одной.

Трюк с ракушкой: любое число

[ редактировать ]

Другой способ добиться аналогичного эффекта — использовать оболочку в качестве запускаемой команды и разобраться со сложностью в этой оболочке, например:

$ mkdir ~/backups
$ find /path -type f -name '*~' -print0 | xargs -0 sh -c 'for filename; do cp -a "$filename" ~/backups; done' sh

Слово sh в конце строки — оболочка POSIX. sh -c заполнить для $0, часть позиционных параметров «имя исполняемого файла» (argv). Если бы его не было, имя первого совпадающего файла было бы присвоено $0 и файл не будет скопирован в ~/backups. Для заполнения этого пробела можно также использовать любое другое слово. my-xargs-script например.

С cp принимает несколько файлов одновременно, можно также просто сделать следующее:

$ find /path -type f -name '*~' -print0 | xargs -0 sh -c 'if [ $# -gt 0 ]; then cp -a "$@" ~/backup; fi' sh

Этот скрипт запускается cp со всеми переданными ему файлами при передаче каких-либо аргументов. Это более эффективно, поскольку только один вызов cp выполняется для каждого вызова sh.

Проблема сепаратора

[ редактировать ]

Многие утилиты Unix ориентированы на строки. Они могут работать с xargs пока строки не содержат ', ", или пробел. Некоторые утилиты Unix могут использовать NUL в качестве разделителя записей (например, Perl (требуется -0 и \0 вместо \n), locate (требуется использование -0), find (требуется использование -print0), grep (требует -z или -Z), sort (требуется использование -z)). С использованием -0 для xargs решает эту проблему, но многие утилиты Unix не могут использовать NUL в качестве разделителя (например, head, tail, ls, echo, sed, tar -v, wc, which).

Но часто люди забывают об этом и полагают, что xargs также линейно-ориентирован, что не так (по умолчанию xargs разделяется на символы новой строки и пробелы внутри строк, подстроки с пробелами должны быть заключены в одинарные или двойные кавычки).

Проблема сепаратора проиллюстрирована здесь:

# Make some targets to practice on
touch important_file
touch 'not important_file'
mkdir -p '12" records'

find . -name not\* | tail -1 | xargs rm
find \! -name . -type d | tail -1 | xargs rmdir

Выполнение вышеуказанного приведет к important_file будет удален, но не удалит ни каталог с именем 12" records, ни файл с именем not important_file.

Правильное решение — использовать специфичный для GNU -print0 вариант, но tail (и другие инструменты) не поддерживают строки, завершающиеся NUL:

# use the same preparation commands as above
find . -name not\* -print0 | xargs -0 rm
find \! -name . -type d -print0 | xargs -0 rmdir

При использовании -print0 вариант, записи разделяются нулевым символом вместо конца строки. Это эквивалентно более подробной команде: find . -name not\* | tr \\n \\0 | xargs -0 rm или короче, переключая xargs в (не POSIX) строчно-ориентированный режим с -d (разделитель) вариант: find . -name not\* | xargs -d '\n' rm

но в целом использую -0 с -print0 следует отдавать предпочтение, поскольку переводы строк в именах файлов по-прежнему являются проблемой.

ГНУ parallel является альтернативой xargs который предназначен для тех же возможностей, но ориентирован на линии. Таким образом, используя вместо этого GNU Parallel, вышеописанное будет работать так, как ожидалось. [7]

Для сред Unix, где xargs не поддерживает -0 ни -d (например, Solaris, AIX), стандарт POSIX утверждает, что можно просто экранировать каждый символ обратной косой чертой: find . -name not\* | sed 's/\(.\)/\\\1/g' | xargs rm. [8] В качестве альтернативы можно вообще избежать использования xargs, либо используя GNU Parallel, либо используя -exec ... + функциональность find.

Работа с подмножеством аргументов одновременно

[ редактировать ]

Можно иметь дело с командами, которые могут принимать только один или два аргумента одновременно. Например, diff Команда работает с двумя файлами одновременно. -n возможность xargs указывает, сколько аргументов одновременно следует передать данной команде. Команда будет вызываться повторно, пока все входные данные не будут исчерпаны. Обратите внимание, что при последнем вызове можно получить меньше аргументов, чем желаемое, если входных данных недостаточно. Использовать xargs чтобы разбить ввод на два аргумента в каждой строке:

$ echo {0..9} | xargs -n 2
0 1
2 3
4 5
6 7
8 9

Помимо запуска на основе заданного количества аргументов одновременно, можно также вызывать команду для каждой строки ввода с помощью -L 1 вариант. Одновременно можно использовать произвольное количество строк, но чаще всего используется одна. Вот как можно diff каждый git коммит против своего родителя. [9]

$ git log --format="%H %P" | xargs -L 1 git diff

Проблема с кодировкой

[ редактировать ]

Обработка разделителя аргументов xargs это не единственная проблема с использованием xargs программа в режиме по умолчанию. Большинство инструментов Unix, которые часто используются для управления именами файлов (например, sed, basename, sortи т. д.) являются инструментами обработки текста. Однако имена путей Unix на самом деле не являются текстом. Рассмотрим путь /aaa/bbb/ccc. Каталог /aaa и его подкаталог bbb обычно могут создаваться разными пользователями в разных средах. Это означает, что у этих пользователей могут быть разные настройки локали, а это означает, что aaa и bbb даже не обязательно должны иметь одинаковую кодировку символов. Например, aaa может быть в UTF-8, а bbb — в Shift JIS. В результате имя абсолютного пути в системе Unix может быть неправильно обработано как текст в односимвольной кодировке. Инструменты, которые полагаются на текстовые входные данные, могут не работать с такими строками.

Одним из способов решения этой проблемы является запуск таких инструментов в локали C, которая по существу обрабатывает байты ввода как есть. Однако это изменит поведение инструментов так, как пользователь может не ожидать (например, некоторые ожидания пользователя относительно поведения свертывания регистра могут не оправдаться).

  1. ^ «Список сокращений Unix: Полный список» . www.roesler-ac.de . Проверено 12 апреля 2020 г.
  2. ^ «Собственные порты Win32 некоторых утилит GNU» . unxutils.sourceforge.net .
  3. ^ «Средства обработки текста для Windows» .
  4. ^ ИБМ . «Программирование Qshell в IBM System i версии 7.2» (PDF) . Проверено 05 сентября 2020 г.
  5. ^ «Часто задаваемые вопросы по основным утилитам GNU» . Проверено 7 декабря 2015 г.
  6. ^ «Максимальная длина аргументов для нового процесса» . www.in-ulm.de .
  7. ^ Различия между xargs и GNU Parallel . GNU.org . По состоянию на февраль 2012 г.
  8. ^ xargs – Справочник по оболочке и утилитам, Единая спецификация UNIX , версия 4 от Open Group.
  9. ^ Космин Стеджеран. «Вещи, которые вы (вероятно) не знали о xargs» . Проверено 7 декабря 2015 г.
[ редактировать ]

Страницы руководства

[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 2029d8f8867bdb84a53e887734f237b5__1715362920
URL1:https://arc.ask3.ru/arc/aa/20/b5/2029d8f8867bdb84a53e887734f237b5.html
Заголовок, (Title) документа по адресу, URL1:
xargs - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)