Согласно странице руководства, xargs завершит работу, если одна из строк выполнения завершится с ошибкой 255:
Если любой вызов команды завершается со статусом 255, xargs немедленно останавливается, не считывая никаких дальнейших вводимых данных. Когда это происходит, на stderr выдается сообщение об ошибке.
Как мне получить xargs на не сделай это?
У меня есть пакетное задание из 1500 строк, которое я хочу выполнить, по 50 строк за раз. Я обнаруживал, что он всегда умирал на определенном этапе, а не завершал работу. Не хорошо!
Еще лучший вопрос, вопрос, описывающий то, что я пытаюсь сделать:
Как я могу запустить пакетный сценарий из 1500 строк, по 50 строк за раз, чтобы он не завершал работу в середине и чтобы вывод записывался в какой-то файл журнала?
Похожий на larsks
ответ, но более явный:
xargs sh -c "somecommand || true"
Вы можете обернуть Perl-скрипт другим простым bash-скриптом:
#!/bin/bash
real-command "$@" || exit 0
Это вызовет настоящая команда передавая ему все параметры, которые вы передаете этому фальшивая команда и он всегда будет возвращать код выхода 0 (что означает, что он всегда успешен), и xargs никогда не остановится на этом.
Вы можете написать свой вызов xargs, чтобы замаскировать коды возврата ваших командных строк. Примерно так:xargs
никогда не увидит коды выхода, возвращаемые некоторая команда:
xargs sh -c "somecommand || :"
Только что нашел забавный ответ на этот вопрос, хотя его полезность будет зависеть от команды, которую вы пытаетесь запустить.
Если вы используете xargs, чтобы собрать список команд, вы можете получить такое поведение, указав xargs повторить команду, а затем подключившись к bash.
Например, если вы пытаетесь удалить список вещей, которые могут существовать, а могут и не существовать:
# presume this will fail in a similar way to your command
cat things_to_delete | xargs -n1 delete_command_that_might_exit
# instead echo the commands and pipe to bash
cat things_to_delete | xargs -n1 echo delete_command_that_might_exit | bash
Это работает, потому что, во-первых, xargs всегда вызывает только echo, поэтому он не видит никаких ошибок. Затем, во-вторых, потому что поведение bash по умолчанию - продолжить выполнение после неудачного оператора.
Чтобы быть более конкретным в моем случае, я использовал это, чтобы удалить несколько старых версий приложений из AWS ElasticBeanstalk, например:
aws elasticbeanstalk describe-application-versions --application-name myapp |\
jq -r '.ApplicationVersions | sort_by(.DateCreated) | .[0:-10] | .[].VersionLabel' |\
xargs -n1 \
echo aws elasticbeanstalk delete-application-version \
--delete-source-bundle --application-name myapp --version-label |\
bash
Следующие строительные работы для меня:
ls | xargs -I % svn upgrade %
Даже если обновление svn не удалось на каком-то элементе, процесс был продолжен
Если бы вы использовали xargs
с участием find
, использовать -exec
вариант find
вместо:
find . -name '*.log' -exec somecommand {} \;