Имя.

xargs - построение и выполнение командных строк из стандартного ввода

Краткий обзор.

xargs [параметры] [command [initial-arguments]]

Описание.

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

Командная строка для команды наращивается до тех пор, пока не достигнет определенного системой предела (если не используются опции -n и -L). Указанная команда будет вызываться столько раз, сколько необходимо для использования списка входных элементов. В общем, будет намного меньше вызовов команды, чем было элементов во входных данных. Обычно это дает значительные преимущества в производительности. Некоторые команды также могут с пользой выполняться параллельно; см. параметр -P.

Поскольку имена файлов Unix могут содержать пробелы и новые строки, такое поведение по умолчанию часто вызывает проблемы; имена файлов, содержащие пробелы и/или новые строки, неправильно обрабатываются xargs. В таких ситуациях лучше использовать опцию -0, которая предотвращает подобные проблемы. При использовании этого параметра вам нужно будет убедиться, что программа, которая производит ввод для xargs, также использует нулевой символ в качестве разделителя. Если эта программа, например, GNU find, опция -print0 сделает это за вас.

Если какой-либо вызов команды завершится со статусом 255, xargs немедленно остановится, не считывая никаких дальнейших входных данных. Когда это происходит, на stderr выдается сообщение об ошибке.

Параметры.

-0, --null
Входные элементы заканчиваются нулевым символом вместо пробела, а кавычки и обратная косая черта не являются специальными (каждый символ воспринимается буквально). Отключает конец строки файла, который обрабатывается как любой другой аргумент. Полезно, когда элементы ввода могут содержать пробелы, кавычки или обратную косую черту. Опция GNU find -print0 выдает входные данные, подходящие для этого режима.

-a file, --arg-file=file
Чтение элементов из файла вместо стандартного ввода. Если вы используете эту опцию, stdin остается неизменным при выполнении команд. В противном случае stdin перенаправляется из /dev/null.

--delimiter=delim, -d delim
Входные элементы заканчиваются указанным символом. Указанный разделитель может быть одиночным символом, экранирующим символом в стиле C, таким как \n, или восьмеричным или шестнадцатеричным экранирующим кодом. Восьмеричный и шестнадцатеричный экранирующий-код понимаются как для команды printf. Многобайтовые символы не поддерживаются. При обработке входных данных кавычки и обратная косая черта не являются чем-то особенным; каждый символ во входных данных воспринимается буквально. Параметр -d отключает любую строку конца файла, которая обрабатывается как любой другой аргумент. Вы можете использовать этот параметр, когда входные данные состоят просто из элементов, разделенных новой строкой, хотя почти всегда лучше проектировать свою программу так, чтобы использовать --null там, где это возможно.

-E eof-str
Установить в конце строки файла значение eof-str. Если конец строки файла встречается в строке ввода, остальная часть ввода игнорируется. Если ни -E, ни -e не используются, конец строки файла не используется.

-e[eof-str], --eof[=eof-str]
Этот параметр является синонимом параметра -E. Вместо этого используйте -E, потому что он совместим с POSIX, а этот параметр - нет. Если eof-str опущен, то конец строки файла отсутствует. Если ни -E, ни -e не используются, конец строки файла не используется.

-I replace-str
Заменить вхождения replace-str в начальных аргументах именами, считанными из стандартного ввода. Кроме того, пробелы без кавычек не завершают входные элементы; вместо этого разделителем является символ новой строки. Подразумевает -x и -L 1.

-i[replace-str], --replace[=replace-str]
Этот параметр является синонимом -Ireplace-str, если указано replace-str. Если аргумент replace-str отсутствует, эффект будет таким же, как и от -I{}. Этот параметр устарел; вместо этого используйте -I.

-L max-lines
Использовать не более max-lines непустых строк ввода для каждой командной строки. Завершающие пробелы приводят к тому, что строка ввода логически продолжается в следующей строке ввода. Подразумевает -x.

-l[max-lines], --max-lines[=max-lines]
Синоним для параметра -L. В отличие от -L, аргумент max-lines является необязательным. Если максимальное количество строк не указано, по умолчанию оно равно единице. Параметр -l устарел, поскольку стандарт POSIX вместо него указывает -L.

-n max-args, --max-args=max-args
Использовать не более max-args аргументов для каждой командной строки. При превышении количества (см. параметр -s) будет использоваться меньше аргументов max-args, если не задана опция -x, в этом случае xargs завершит работу.

-P max-procs, --max-procs=max-procs
Запускать до max-procs процессов одновременно; значение по умолчанию равно 1. Если max-procs равно 0, xargs будет запускать как можно больше процессов одновременно. Используйте опцию -n или опцию -L с -P; в противном случае, скорее всего, будет выполнен только один exec. Во время работы xargs вы можете отправить его процессу сигнал SIGUSR1, чтобы увеличить количество команд для одновременного выполнения, или SIGUSR2, чтобы уменьшить их количество. Вы не можете увеличить его выше определенного реализацией предела (который отображается с помощью --show-limits). Вы не можете уменьшить его ниже 1. Команда xargs никогда не завершает свои процессы; когда его просят уменьшить, он просто ожидает завершения более чем одной существующей процесса, прежде чем запускать другой.

Пожалуйста, обратите внимание, что правильное управление параллельным доступом к общим ресурсам зависит от вызываемых процессов. Например, если несколько из них попытаются выполнить печать в stdout, выходные данные будут получены в неопределенном порядке (и, скорее всего, перепутаны), если процессы каким-либо образом не взаимодействуют, чтобы предотвратить это. Использование какой-либо схемы блокировки является одним из способов предотвращения таких проблем. В целом, использование схемы блокировки поможет обеспечить корректный вывод, но снизит производительность. Если вы не хотите мириться с разницей в производительности, просто организуйте для каждого процесса создание отдельного выходного файла (или иным образом используйте отдельные ресурсы).

-o, --open-tty
Повторно открыть stdin как /dev/tty в дочернем процессе перед выполнением команды. Это полезно, если вы хотите, чтобы xargs запускал интерактивное приложение.

-p, --interactive
Предложить пользователю запустить каждую командную строку и прочитать строку из терминала. Запускать командную строку только в том случае, если ответ начинается с `y' или `Y'. Подразумевает -t.

--process-slot-var=name
Установить для имени переменной окружения уникальное значение в каждом запущенном дочернем процессе. Значения используются повторно после завершения дочерних процессов. Это может быть использовано, например, в элементарной схеме распределения нагрузки.

-r, --no-run-if-empty
Если стандартный ввод не содержит непустых строк, не выполнять команду. Обычно команда выполняется один раз, даже если ввода нет. Этот параметр является расширением GNU.

-s max-chars, --max-chars=max-chars
Использовать не более max-chars символов в командной строке, включая команду и начальные аргументы, а также завершающие нули в концах строк аргументов. Наибольшее допустимое значение зависит от системы и вычисляется как ограничение длины аргумента для exec, за вычетом размера вашей среды, за вычетом запаса в 2048 байт. Если это значение больше 128 КБ, в качестве значения по умолчанию используется 128 КБ; в противном случае значение по умолчанию является максимальным. 1 КБ - это 1024 байта. Команда xargs автоматически адаптируется к более жестким ограничениям.

--show-limits
Отобразить ограничения на длину командной строки, которые накладывает операционная система, выбор размера буфера xargs и параметр -s. Передайте входные данные из /dev/null (и, возможно, укажите --no-run-if-empty), если вы не хотите, чтобы xargs что-либо делал.

-t, --verbose
Печать командной строки на стандартный вывод ошибок перед ее выполнением.

-x, --exit
Выйти, если превышен размер (см. опцию -s).

--help
Распечатать сводку параметров в xargs и завершить работу.

--version
Вывод номера версии xargs и завершить работу.

Примеры.

find /tmp -name core -type f -print | xargs /bin/rm -f

Найти файлы с именем core в каталоге /tmp или ниже него и удалить их. Обратите внимание, что это будет работать неправильно, если есть какие-либо имена файлов, содержащие новые строки или пробелы.

find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f

Найти файлы с именем core в каталоге /tmp или ниже него и удалить их, обработав имена файлов таким образом, чтобы имена файлов или каталогов, содержащие пробелы или новые строки, обрабатывались правильно.

find /tmp -depth -name core -type f -delete

Найти файлы с именем core в каталоге /tmp или ниже него и удалить их, но более эффективно, чем в предыдущем примере (потому что мы избегаем необходимости использовать fork(2) и exec(2) для запуска rm, и нам не нужен дополнительный процесс xargs).

cut -d: -f1 < /etc/passwd | sort | xargs echo

Генерирует компактный список всех пользователей в системе.

Статус выхода.

xargs завершает работу со следующим статусом:
0, если он успешен
123, если любой вызов команды завершился со статусом 1-125
124, если команда завершилась со статусом 255
125, если команда завершена сигналом
126, если команда не может быть выполнена
127, если команда не найдена
1, если произошла какая-то другая ошибка.

Коды выхода, превышающие 128, используются оболочкой для указания того, что программа умерла из-за фатального сигнала.

Соответствие стандартам.

Начиная с версии GNU xargs 4.2.9, по умолчанию xargs не имеет логического маркера конца файла. POSIX (IEEE Std 1003.1, 2004 Edition) позволяет это сделать.

Опции -l и -i появились в версии стандарта POSIX 1997 года, но не появились в версии стандарта 2004 года. Поэтому вместо них следует использовать -L и -I соответственно.

Опция -o является расширением стандарта POSIX для лучшей совместимости с BSD.

Стандарт POSIX позволяет реализациям иметь ограничение на размер аргументов функций exec. Этот предел может составлять всего 4096 байт, включая размер среды. Чтобы скрипты были переносимыми, они не должны полагаться на большее значение. Однако я не знаю ни одной реализации, в которой фактический предел был бы настолько мал. Опция --show-limits может быть использована для обнаружения фактических ограничений, действующих в текущей системе.

Смотрите также.

find(1), locate(1), locatedb(5), updatedb(1), fork(2), execvp(3), kill(1), signal(7),

Полная документация по xargs ведется в виде руководства Texinfo. Если программы info и xargs правильно установлены на вашем сайте, команда info xargs должна дать вам доступ к полному руководству.

Ошибки.

Параметр -L несовместим с параметром -I, но, возможно, этого не должно быть.

Безопасное использование xargs невозможно, поскольку между созданием списка входных файлов и их использованием в командах, которые выдает xargs, всегда будет промежуток времени. Если другие пользователи имеют доступ к системе, они могут манипулировать файловой системой в течение этого временного окна, чтобы принудительно применить действие команд, выполняемых xargs, к файлам, которые вы не намеревались. Для более подробного обсуждения этой и связанных с ней проблем, пожалуйста, обратитесь к главе "Соображения безопасности" в документации findutils Texinfo. Параметр -execdir в find часто можно использовать в качестве более безопасной альтернативы.

Когда вы используете опцию -I, каждая строка, считанная из входных данных, буферизуется внутри. Это означает, что существует верхний предел длины входной строки, который xargs будет принимать при использовании с опцией -I. Чтобы обойти это ограничение, вы можете использовать параметр -s для увеличения объема буферного пространства, используемого xargs, и вы также можете использовать дополнительный вызов xargs, чтобы гарантировать, что не будут возникать очень длинные строки. Например:

somecommand | xargs -s 50000 echo | xargs -I '{}' -s 100000 rm '{}'

Здесь первый вызов xargs не имеет ограничения на длину входной строки, поскольку не используется опция -i. Второй вызов xargs действительно имеет такой предел, но мы убедились, что он никогда не встретит строку длиннее, чем он может обработать. Это не идеальное решение. Вместо этого опция -i не должна накладывать ограничение на длину строки, вот почему это обсуждение появляется в разделе Ошибки. Проблема не возникает с выводом find(1), потому что он выдает только одно имя файла в строке.

Лучший способ сообщить об ошибке - использовать форму по адресу http://savannah.gnu.org/bugs/?group=findutils. Причина этого заключается в том, что тогда вы сможете отслеживать прогресс в устранении проблемы. Другие комментарии о xargs(1) и о пакете findutils в целом можно отправить в список рассылки bug-findutils. Чтобы присоединиться к списку, отправьте электронное письмо на bug-findutils-request@gnu.org.