Понимание команды xargs UNIX
Я в значительной степени запутался в этом. Нужны некоторые разъяснения.
Пример 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) один или несколько раз с любым initial-аргументы, за которыми следуют элементы, считываемые из стандартного ввода. Пустая строка на стандартном входе игнорируются.
5 ответов
В общем xargs используется следующим образом
утилита prog | xargs
здесь prog ожидается, что выход один или более строки/пробел результаты. Фокус в том, что xargs не! нессарлы зов утилиты один раз для каждого результата, вместо этого разбивает список результатов на подсписки и вызывает утилиты для каждого подсписка. Если вы хотите заставить xargs позвонить утилиты для каждого результата вам нужно будет вызывать его с команды xargs -Л1.
отметим, что xargs обещает вам, что подсписок отправлено утилиты меньше, чем ARG_MAX (вот как он избегает этих страшных список аргументов для long ошибки). Вы можете получить текущее значение ARG_MAX используя getconf ARG_MAX
хорошим примером того, что делает xargs, является попытка получить отсортированные контрольные суммы для каждого файла в каталоге с помощью find.
find . | cksum | sort
возвращает только одну контрольную сумму, и неясно, для чего это контрольная сумма. Не то, что мы хотим. Труба отправляет stdout из find в stdin для cksum. То, что cksum действительно хочет, - это список args командной строки, например
cksum file001.blah file002.blah file003.blah
сообщит три строки, по одной на файл, с требуемыми контрольными суммами. Xargs делает волшебный трюк-преобразование stdout предыдущей программы во временную и скрытую командную строку для подачи в следующую. Командная строка, которая работает:
find . | xargs cksum | sort
Примечание нет трубы между xargs и cksum.
$ echo 'line1
> line2
> line3
> ...
> lineN ' | xargs cmd1 -a -b
в результате:
$ cmd1 -a -b line1 line2 line3 ... lineN
xargs
сломается cmd1 ...
в несколько казней cmd1
если количество строк становится слишком большим.
xargs
может использоваться для многих других задач, связанных с прохождением stdin
строки как аргументы. Взгляните на столицу на xargs (1) для выполнения нескольких экземпляров команды параллельно.
xargs обычно используется для группировки аргументов вместе, чтобы вы не получили ошибку "слишком много аргументов", которая возникает, когда вы передаете большое количество аргументов команде
#!/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
не будет работать, так как максимальное количество параметров превышено (я не уверен, что Макс, но давайте скажем его 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 параметра