Какие команды могут запускать xargs?

Из руководства по findutils:

xargs [option...] [command [initial-arguments]] 

Правильно ли я понимаю, что xargs запускает command за несколько прогонов, каждый из которых имеет свою последовательность аргументов?

Если да, означает ли это, что такая команда должна удовлетворять тому, что применение последовательности аргументов к команде фактически совпадает с

  • разбиение последовательности аргументов на подпоследовательности, и

  • запустить команду с каждой подпоследовательностью аргументов в другом прогоне?

Например, правильно ли, что если mycommand может быть запущен xargs , то

 mycommand arg1 arg2 arg3 

должно быть эффективно так же, как

 mycommand arg1 mycommand arg2 arg3 

Является ли указанное выше условие необходимым и достаточным для выполнения команды xargs ?

Есть ли команда, которая не удовлетворяет вышеуказанному условию? (Я не могу их найти.) Если есть, может ли он работать под управлением xargs ?

Могут ли аргументы, передаваемые командой xargs быть аргументами любого типа: опциями, аргументами опций или аргументами без опций? Я думаю, что этот вопрос полезен для ответа на вышеуказанные вопросы.

Что, если задействован -i of xargs ?

Благодарю.

Правильно ли я понимаю, что xargs запускает команду за несколько прогонов, каждый из которых имеет свою последовательность аргументов?

Да (если, конечно, ввод в xargs повторяется)

 mycommand arg1 arg2 arg3 

должно быть эффективно так же, как

 mycommand arg1 mycommand arg2 arg3 

В значительной степени, поскольку в общем случае мы не можем знать, где xargs разделит список. GNU xargs имеет --show-limits limit, который можно использовать для определения того, подходит ли весь ввод за один запуск команды.

Конечно, если аргументы должны быть переданы команде в наборах из N , мы можем использовать -n N чтобы иметь некоторый контроль над ней (или -n M с M, кратным N ).

Есть ли команда, которая не удовлетворяет вышеуказанному условию? (Я не могу их найти.) Если есть, может ли он работать под управлением xargs?

Кусалананда упомянул М.В., у которого есть проблема, что последний аргумент трактуется иначе, чем другие. По сути, аргументы, добавленные xargs , должны идти посередине, и стандартного способа сделать это не существует. (FreeBSD xargs имеет -J {} который делает это, а GNU mv имеет опцию -t dir для передачи целевого каталога в начале списка аргументов. cp похож.)

Тогда что-то вроде tar -czf foo.tar.gz не будет работать, так как -c (create) перезаписывает архив при каждом запуске. Этого можно избежать, используя -r (append) вместо -c , но по крайней мере GNU tar не поддерживает добавление в сжатый архив.

К счастью, большинство утилит работают файл-за-файлом и в конце принимают список файлов.

Могут ли аргументы, передаваемые командой xargs, быть аргументами любого типа: опциями, аргументами опций или аргументами без опций?

Они просто строки, xargs не знает, что они имеют в виду. Если бы у вас была утилита, которая не принимала обычный список файлов, но использовала опцию -f filename , вы могли бы устроить так, чтобы xargs получал входные данные, такие как -f file1 -f file2 ... и она с радостью передала бы это. Хотя при большом количестве входных данных ограничение по размеру может снова привести к разделению между -f и именем файла, но добавление чего-то вроде -n 100 сделает это маловероятным (в зависимости от длины имен файлов и фактического ограничения размера).

Что, если задействован -i of xargs?

-i в GNU xargs – это то же самое, что и -I {} , и несколько скучно заставляет xargs запускать команду один раз для каждого входного аргумента. Помогает, если вам нужно поместить аргумент в середину команды, но на самом деле не помогает уменьшить количество вызовов для команды.

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

 echo 1 2 3 | xargs echo "-" - 1 2 3 

Здесь xargs читает 1, 2 и 3 и запускает echo "-" 1 2 3 . Я включаю "-" чтобы прояснить, сколько раз вызывается echo .

Вы можете ограничить количество аргументов, которые она будет передавать команде, используя опцию -n :

 echo 1 2 3 | xargs -n2 echo "-" - 1 2 - 3 

Здесь xargs читает 2 xargs (максимум) из своего стандартного входного streamа и запускает команду с этими токенами в качестве параметров командной строки: echo "-" 1 2 . Поскольку он еще не закончил чтение токенов из стандартного ввода, он продолжил чтение 3, обнаружил EOF и снова выполнил команду с остальными параметрами: echo "-" 3 .

Регулировка значения n даст вам другое поведение:

 echo 1 2 3 | xargs -n1 echo "-" - 1 - 2 - 3 

Редактировать: Тим прокомментировал, что я не отвечал на его вопросы. Я не согласен и постараюсь явно обзвонить ответы ниже:

Правильно ли я понимаю, что xargs запускает command за несколько прогонов, каждый из которых имеет свою последовательность аргументов?

Я обратился к этому вопросу. Он может запустить команду в один или несколько запусков. По умолчанию он пытается выполнить command как можно меньше раз (ограничено длиной аргумента).

Если да, означает ли это, что такая команда должна удовлетворять тому, что применение последовательности аргументов к команде фактически совпадает с (x) разбиением последовательности аргументов на подпоследовательности и (x) выполнением команды с каждой подпоследовательностью аргументов другой пробег?

Я обратился к этому вопросу. Если токены слишком длинные (или ограничены параметром -n , xargs разбивает их на подпоследовательности и запускает команду с подпоследовательностями. Я даже xargs примеры этого).

Является ли указанное выше условие необходимым и достаточным для выполнения команды xargs ?

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

Есть ли команда, которая не удовлетворяет вышеуказанному условию? (Я не могу их найти.) Если есть, может ли он работать под управлением xargs?

Опять же, вы можете тщательно обработать такой случай (но я бы не рекомендовал его). Тщательно разработанный пример (работает mv a.txt b.txt ):

 $ ls a.txt $ echo a.txt b.txt | xargs mv $ ls b.txt 

Могут ли аргументы, передаваемые командой xargs, быть аргументами любого типа: опциями, аргументами опций или аргументами без опций? Я думаю, что этот вопрос полезен для ответа на вышеуказанные вопросы.

Они читаются токенами, разделенными пробелом. Они передаются команде в качестве аргументов, разделенных пробелом. Это запустит ls -l :

 $ echo -l | xargs ls total 0 -rw-r----- 1 user group 0 Jun 7 15:16 b.txt 

Что, если задействован -i of xargs ?

Хорошо, я не ответил на этот вопрос, но я не совсем понимаю, что вы спрашиваете в этом контексте.