Понимание команды UNIX xargs
Я очень смущен этим. Нужны некоторые пояснения.
Пример 1:
pgrep string | xargs ps
Пример 2:
find . | xargs grep whatever
Из примера 1 я собираю его следующим образом:
Найдите строку, которая является частью имени запущенного процесса и возвращает идентификаторы процессов всех совпадений в "xargs ps" → , которые просто присоединяют ps к совпадениям (которые сами являются самими процессами) получить тот же результат, что и:
ps <processid>
Может кто-нибудь объяснить, что действительно делает xargs в этом случае?
Из примера 2 я собираю его следующим образом:
Это, чтобы найти некоторую "строку" рекурсивно из текущего рабочего каталога.
Здесь, как работает "xargs"?
Я считал, что "xargs" повторно добавляет данные со стандартного ввода в "аргумент", заданный для xargs (который обычно является командой UNIX сам по себе).
Из справочной страницы xargs():
xargs считывает элементы со стандартного ввода, разделенные пробелами (которые могут быть защищенные двойными или одинарными кавычками или обратная косая черта) или новые строки и выполняет команду (по умолчанию -/bin/echo) один или несколько раз с любым начальные аргументы, за которыми следуют элементы, считанные со стандартного ввода. Пустые строки на стандартном входе игнорируются.
Ответы
Ответ 1
В общем, xargs используется так
prog | xargs utility
где prog
ожидаются к выходу одного или более новая строка/разделенному пробел результаты. Хитрость в том, что xargs
не обязательно вызывает utility
один раз для каждого результата, вместо этого он разбивает результаты на подсписки и вызывает utility
для каждого подсписка. Если вы хотите заставить xargs вызывать utility
для каждого результата, вам нужно будет вызвать ее с помощью xargs -L1
.
Обратите внимание, что xargs
обещает вам, что Подсписок отправляется utility
короче ARG_MAX
(Если вам интересно, вы можете получить текущее значение ARG_MAX
с помощью getconf ARG_MAX
.) Это, как он избегает тех страшных "список аргументов для длинных" ошибок.
Ответ 2
Хорошим примером того, что делает xargs, является попытка получить отсортированные контрольные суммы для каждого файла в каталоге с помощью find.
find . | cksum | sort
возвращает только одну контрольную сумму, и это не понятно, для чего это контрольная сумма. Не то, что мы хотим. Труба отправляет stdout из find в stdin для cksum. То, что действительно хочет cksum, это список аргументов командной строки, например
cksum file001.blah file002.blah file003.blah
будет сообщать три строки, по одному на файл, с требуемыми контрольными суммами. Xargs делает магический трюк - преобразование stdout предыдущей программы во временную и скрытую командную строку для подачи следующего. Командная строка, которая работает:
find . | xargs cksum | sort
Обратите внимание на отсутствие связи между xargs и cksum.
Ответ 3
$ echo 'line1
> line2
> line3
> ...
> lineN ' | xargs cmd1 -a -b
приведет к:
$ cmd1 -a -b line1 line2 line3 ... lineN
xargs
разбивает cmd1 ...
на несколько выполнений cmd1
, если количество строк становится слишком большим.
xargs
может использоваться для многих других задач, связанных с передачей строк stdin
в качестве позиционных аргументов. Взгляните на параметр капитала -P
в xargs (1) для одновременного запуска нескольких экземпляров команды.
Ответ 4
xargs обычно используется для группировки аргументов вместе, так что вы не получаете ошибку "слишком много аргументов", которая возникает, когда вы передаете большое количество аргументов команде
Ответ 5
#!/bin/sh
#script to echo out the arguments 1 at a time!
for a in $*
do
echo $a
done
команда
$sh myscript 1 2 3 4 5
даст
1
2
3
4
5
но
$sh myscript 1 2 3 4 5 6 7 8 9 10 11
не будет работать, поскольку максимальное количество параметров будет превышено (im действительно не уверен, что такое max, но позволяет сказать его 10 для этого примера!)
Чтобы обойти это, мы могли бы использовать
#!/bin/sh
#script to echo out the arguments 1 at a time!
for a in $*
do
echo $a | xargs echo
done
мы могли бы запустить его следующим образом
$sh myscript "1 2 3 4 5" "6 7 8 9 10 11"
и получить правильный результат, так как есть только 2 параметра