xargs вернул 123: находим отказ внутри пакетного запуска
Пакетная обработка завершилась с кодом 123, хотя рабочая программа обычно возвращает только 0 или 7. В логе несколько перемешанных сообщений, и непонятно, какой вход не обработан. Такой код мог вернуть сам xargs: он сворачивает результаты нескольких запусков в общий статус. Чтобы понять проблему, нужно сохранить контекст каждого дочернего вызова.
В GNU xargs статус 123 означает, что хотя бы один запуск вернул значение от 1 до 125. Это не исходный код конкретной задачи. Если запусков несколько, общий результат не содержит ни имени входа, ни полного списка отказов. Поэтому подпись работы должна появляться там, где ещё известен конкретный аргумент.
Сделаем отказ воспроизводимым
Пример передаёт три логических задания, а задача bad намеренно возвращает 7. Он не читает реальные файлы и не меняет сервисы.
printf '%s\0' first bad last | xargs -0 -n 1 sh -c '
item=$1
printf "start: %s\n" "$item"
if [ "$item" = bad ]; then
printf "failed: %s; exit=7\n" "$item" >&2
exit 7
fi
printf "done: %s\n" "$item"
' worker
status=$?
printf 'xargs=%s\n' "$status"
В итоговой строке GNU xargs должен показать 123. При этом лог назовёт bad и исходный статус 7. Задание last всё ещё может выполниться: обычный ненулевой результат ребёнка не означает немедленную остановку всего обхода.
Слово worker после текста sh -c занимает $0 внутренней оболочки. Реальный вход попадает в $1. Если убрать worker, первый аргумент станет $0, а $1 окажется пустым. Этот сдвиг часто путают с потерей записи самим xargs, хотя правило задаёт интерфейс shell.
Один вход и пакет входов
Параметр -n 1 нужен здесь ради ясной подписи каждого задания. Реальные утилиты часто умеют принять несколько файлов сразу. Тогда больший пакет уменьшает число запусков, но диагностировать отказ приходится по логу самой программы: один статус относится сразу к нескольким входам.
Не сочетайте без причины -n с -I: у GNU xargs эти режимы имеют пересекающееся назначение, а их совместное поведение требует внимания к порядку опций. Для простой передачи списка в argv обычно достаточно -n и явного sh -c только там, где действительно нужна shell-логика. Если программа уже делает всю работу, вызывайте её непосредственно.
Нулевой разделитель сохраняет пробелы и переводы строк в аргументах. Он не защищает от исполнения данных, если подставлять их прямо в текст shell-команды. В примере текст скрипта фиксирован, а item приходит позиционным параметром. Это правило следует сохранить при замене учебного условия на рабочую операцию.
Как менять политику остановки
У GNU xargs код 255 дочерней команды имеет особое значение: утилита прекращает дальнейшее чтение входов и возвращает 124. Не используйте его как обычный код предметной ошибки без понимания последствий. Для параллельных запусков уже работающие задачи всё равно требуют отдельного учёта и завершения.
Пустой вход — ещё одна отдельная проверка. GNU xargs по умолчанию способен вызвать команду даже без входных аргументов; -r запрещает такой запуск. В примере список непустой, но перед подключением к find или внешней выгрузке определите, должна ли пустота означать «нет работы» или ошибку предыдущего шага.
В курсе Linux и Bash проверка ошибок и корректная передача аргументов включены в программу. Откройте её и продолжите к пакетной автоматизации, где по итоговому статусу видно наличие проблемы, а по диагностике — конкретное задание и причина отказа.
Ещё по теме
Продолжить на практике
- Linux и Bash для DevOps-инженеров ↗
Linux для работы с серверами: процессы, права, systemd, сеть, диски и логи. Автоматизируйте повседневные задачи на Bash и разберите типичные сбои сервиса — от занятого порта до переполненного диска.
