Иногда я выполняю длинную xargs
работу в одночасье, и действительно раздражает то, что утром он xargs
умер где-то посередине, например, из-за ошибки сегментации в одном особом случае, как это произошло ночью.
Если хотя бы один xargs
ребенок убит, он больше не обрабатывает ввод:
Консоль 1:
[09:35:48] % seq 40 | xargs -i --max-procs=4 bash -c 'sleep 10; date +"%H:%M:%S {}";'
xargs: bash: terminated by signal 15
09:35:58 3
09:35:58 4
09:35:58 2
<Exit with code 125>
Консоль 2:
[09:35:54] kill 5601
Могу ли я как-то предотвратить xargs
остановку обработки какого-либо ввода после смерти дочернего процесса и продолжения обработки?
xargs
версию 4.4.2debian wheezy
и похоже, что все работает нормально, даже если я убиваю определенныйsleep
процесс. Какую версиюxargs
вы используете? возможно, они исправили проблему в последней версии.xargs ... bash -c '...;exit 0'
или дажеxargs ... bash -c '... || echo erk'
parallel -j 1
это возможное решение взломать.Ответы:
Нет, ты не можешь. Из
xargs
источников на savannah.gnu.org :Там нет флага вокруг этой проверки или вокруг функции, которая ее вызывает. Похоже, это связано с макс. Процессорами, что, я полагаю, имеет смысл: если вы установите макс. Прокы достаточно высоко, проверка не будет беспокоить до тех пор, пока не достигнет предела, которого вы никогда не получите.
Лучшим решением для того, что вы пытаетесь сделать, может быть использование GNU Make :
Затем:
будет иметь тот же эффект, и даст вам гораздо лучший контроль.
источник
Казалось бы, один из самых очевидных разговорных выражений упоминается только в других предложениях.
То есть вы можете использовать следующее:
для того, чтобы «форсировать успех».
Обратите внимание, что это соответствует предложению lornix (просто не так много слов).
В любом случае, поскольку это фактически игнорирует фактическое состояние завершения процесса, я бы позаботился о том, чтобы вы каким-то образом сохранили статус подпроцесса для последующего анализа. Например:
true
Здесь несколько избыточна и поэтому это может быть лучше записать в виде:Так как мы, вероятно, хотели бы знать, когда «неудачный» файл не может быть затронут. Другими словами, мы больше не игнорируем ошибку, мы принимаем к сведению и продолжаем.
И, рассмотрев рекурсивный характер этой проблемы, возможно, мы увидим, почему именно xargs не облегчает игнорирование ошибок. Потому что это никогда не является хорошей идеей - вместо этого вы должны улучшить обработку ошибок в процессе, который вы разрабатываете. Однако я считаю, что это понятие более присуще самой «философии Unix».
Наконец, я полагаю, что это то, на что ссылается Джеймс Янгман, рекомендуя
trap
, что, вероятно, можно было бы использовать аналогичным образом. То есть, не игнорируйте проблему ... заманите ее в ловушку и решите ее, или вы проснетесь однажды и обнаружите, что ни одна из подпрограмм не преуспела вообще ;-)источник
Используйте
trap
:Также можно переключиться с оболочки на другой язык, на котором вы также можете установить обработчики сигналов.
Также обратите внимание, что после
bash -c foo..
вы должны указать значение, которое$0
должно принимать (здесьfnord
), чтобы первое слово, полученное с помощьюseq
, не было съедено.источник
Поместите туда другую команду, чтобы «съесть» сигнал от умирающей программы.
Я попробовал ваш пример, изначально как показано, чтобы доказать проблему ... killall sleep убивает процесс сна, прерывает bash и завершает работу xargs.
В качестве теста я вставил команду типа «запустить другую команду» между xargs и bash ... в данном случае «/ usr / bin / time». на этот раз (без каламбура), killall sleep убивает процесс сна, но xargs продолжается.
Вы бы перенаправили вывод времени в / dev / null, и это сделало бы именно то, что вы ищете, без существенной перезаписи существующего процесса.
Я представляю, если бы я задумался на мгновение, я мог бы придумать другую программу, которая сделала бы то же самое без болтовни stderr из '/ usr / bin / time'. Или даже сам напишите, это просто «вилка» (или производная exec ()).
Не забудьте использовать «/ usr / bin / time», так как я не уверен, что встроенное «time» из bash будет делать то же самое «поедание» сигнала.
источник
time
для этой цели будетenv
, поскольку все, что он делает, - это добавляет ноль или более необязательных переменных в среду программы, которую он запускает. Он не выдает собственных выходных данных, и код возврата вызванной программы будет передан обратно к тому, что вызваноenv
.Ни то,
time
ни другое неenv
работало для меня (они передают возвращаемое значение своей дочерней программы), поэтому я написалbliss
:тогда
chmod u+x ~/bliss
и что-то вроде
find_or_similar | xargs ~/bliss fatally_dying_program.sh
источник