2009-12-13 4 views
20

Я в значительной степени смущен этим. Нужны некоторые разъяснения.Понимание команды UNIX xargs

Пример 1:

pgrep string | xargs ps 

Пример 2:

find . | xargs grep whatever 

Из примера 1, я понял, что именно таким образом:

Искать "строка", которая часть имени запущенного процесса и вернуть идентификаторы процессов всех совпадений в «xargs ps» ->, которые просто добавляются пс на матчи (которые сами по себе процесс идентификаторы), чтобы получить тот же результат:

ps <processid> 

Может кто-то объяснить, что xargs действительно в этом случае?

Из примера 2, я понял, что именно таким образом:

Это искать какой-то «строка» рекурсивно из текущего рабочего каталога. Вот как работает «xargs»?

Я считал, что «xargs» неоднократно добавляет данные со стандартного ввода в «аргумент», заданный для xargs (который обычно является командой UNIX сам по себе).

От xargs() мужчину страница:

xargs читает элементы из стандартного ввода, разделенных пробелами (которые могут быть защищенных двойными или одинарными кавычками или обратным косой чертой) или символами новой строкой, и выполняет command (по умолчанию is/bin/echo) один или несколько раз с любыми начальными аргументами , за которыми следуют элементы, считанные со стандартного ввода. Пустые строки на стандартном входе игнорируются.

+0

xargs действует как «командный subtitution» (по крайней мере, с Bash). Он превращает многострочные результаты (вертикальные) в однострочный список аргументов токенов (по горизонтали). (Обратите внимание, что вы можете немного фильтровать результаты (используя sed для ex), прежде чем передавать его через xargs). Плюс xargs обрабатывает ошибку «_too much arguments_», которая может быть заражена до ядра Linux 2.6.23 (см. [Wikipedia] (https://en.wikipedia.org/wiki/Xargs)). Вот еще [другая полезная тема] (http://unix.stackexchange.com/questions/24954/when-is-xargs-needed) – Stphane

ответ

37

В общем xargs используется как этот

прог | xargs утилита

где прог ожидается к выходу одного или более новой строки/разделенных пробелом результатов. Фокус в том, что xargs нет! nessarly вызывать утилиту один раз для каждого результата, вместо этого он разбивает список результатов на подсписки и звонки служебная программа для каждого подсписка. Если вы хотите заставить xargs называть утилитой для каждого результата, вам нужно будет вызвать его с помощью xargs -L1.

Обратите внимание, что xargs обещает вам, что Подсписок отправляется утилит короче ARG_MAX (это, как он избегает тех страшного списка аргументов для длинных ошибок).Вы можете получить текущее значение ARG_MAX использованием getconf ARG_MAX

+1

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

+7

Рассмотрите эту команду «find/etc -type d -depth 1 | xargs echo» который печатает все каталоги в папке/etc (но не в их подкаталогах). Поскольку echo принимает несколько аргументов, результатом является одна длинная строка «/ etc/dir1/etc/dir2 ...». Если вы вместо этого назовете «find/etc -type d -depth 1 | xargs -L1 echo», тогда echo будет вызываться один раз для каждого результата, в результате каждый каталог из/etc будет напечатан на отдельной строке. –

+0

Как передать команды или параметры утилите? Скажем, я хочу запустить uglifyjs и указать и вывести папку для ввода, поступающего в xargs? http://stackoverflow.com/questions/43149786/how-to-process-files-in-nested-directories – Costa

2

xargs обычно используется для аргументов группы вместе, так что вы не получите ошибку «слишком много аргументов», которое происходит, когда вы передаете большое количество аргументов команды

6
$ echo 'line1 
> line2 
> line3 
> ... 
> lineN ' | xargs cmd1 -a -b 

приведет к:

$ cmd1 -a -b line1 line2 line3 ... lineN 

xargs сломается cmd1 ... на несколько расстрелов cmd1, если количество строк становится слишком большим.

xargs может использоваться для многих других задач, связанных с передачей stdin строк в качестве позиционных аргументов. Взгляните на опцию капитала -P в xargs(1) для одновременного запуска нескольких экземпляров команды.

1
#!/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 

не будет работать, так как максимальное число параметров превышено (им на самом деле не уверен, что 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 параметра

+2

Я не знаю, что такое max, но это определенно не 10. И вы можете использовать $ @ вместо $ *. это не очень хороший пример того, как использовать xargs – ghostdog74

9

Хорошим примером того, что делает 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 нет трубы.

+1

btw, это основной ингредиент в моем рецепте поиска дублированных файлов в двух или более каталогах, даже если их имена разные. – DarenW

+0

спасибо за понимание и добавление подробностей в xargs дает команду в действии. найти . | xargs --verbose cksum | Сортировка – kumar

Смежные вопросы