Как заставить 'xargs' проигнорировать выход ребенка и продолжать обрабатывать далее

ZRouter.org является основанным на FreeBSD встроенным микропрограммным обеспечением для встроенных устройств, довольно нового проекта, Вы найдете больше информации в Ежеквартальном Отчете о состоянии FreeBSD. (Это поддерживает основанные на ARM устройства.)

Также обратите внимание, что журнал BSD недавно имел некоторые похожие статьи, они покрыли сценарии NanoBSD с помощью платформы ALIX, например. (Это свободно загрузить, если они получают Ваш почтовый адрес.)

24
05.07.2012, 11:46
5 ответов

Нет, Вы не можете. От xargs источники по savannah.gnu.org:

if (WEXITSTATUS (status) == CHILD_EXIT_PLEASE_STOP_IMMEDIATELY)
  error (XARGS_EXIT_CLIENT_EXIT_255, 0,
         _("%s: exited with status 255; aborting"), bc_state.cmd_argv[0]);
if (WIFSTOPPED (status))
  error (XARGS_EXIT_CLIENT_FATAL_SIG, 0,
         _("%s: stopped by signal %d"), bc_state.cmd_argv[0], WSTOPSIG (status));
if (WIFSIGNALED (status))
  error (XARGS_EXIT_CLIENT_FATAL_SIG, 0,
         _("%s: terminated by signal %d"), bc_state.cmd_argv[0], WTERMSIG (status));
if (WEXITSTATUS (status) != 0)
  child_error = XARGS_EXIT_CLIENT_EXIT_NONZERO;

Нет никакого флага вокруг той проверки, или вокруг функции, которая называет ее. Это, действительно кажется, связано с макс. procs, который я предполагаю, имеет смысл: при установке макс. procs достаточно высоко он не потрудится проверять, пока он не поразил предел, который Вы могли бы получить, чтобы никогда быть.

Лучшее решение для того, что Вы пытаетесь сделать, могло бы состоять в том, чтобы использовать GNU, Сделайте:

TARGETS=$(patsubst %,target-%,$(shell seq 1 40))

all: $(TARGETS)

target-%:
    sleep 10; date +"%H:%M:%S $*"

Затем:

$ make -k -j4 

будет иметь тот же эффект и давать Вам намного лучший контроль.

25
27.01.2020, 19:41

Использовать trap:

$ seq 40 | xargs -i --max-procs=4 bash -c \
 'trap "echo erk; exit 1" INT TERM;  sleep 10; date +"%H:%M:%S {}";' fnord
16:07:39 2
16:07:39 4
erk
16:07:39 1
^C
erk
erk
erk
erk

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

Обратите внимание также на это после bash -c foo.. необходимо указать значение это $0 должен взять (здесь, fnord) так, чтобы первое слово, произведенное seq не становится съеденным.

3
27.01.2020, 19:41

Поместите другую команду там для еды сигнала из программы смерти.

Я попробовал Ваш пример, initally как показано, чтобы доказать, что проблема... 'killall сон' уничтожает спящий процесс, удар прерываний и выходы xargs.

Как тест, я придерживался 'выполненный другая команда' команда типа промежуточный xargs и удар... в этом случае '/usr/bin/time'. на этот раз (никакая игра слов), killall сон уничтожает спящий процесс, но xargs продвигается.

Вы передали бы вывод времени по каналу к/dev/null, и это сделает точно, что Вы ищете без майора, переписывают Вашего существующего процесса.

Я воображаю, обдумываю ли я на мгновение, я мог бы придумать другую программу, чтобы сделать то же без болтовни stderr от '/usr/bin/time'. Или даже запишите тот самостоятельно, это - просто 'ветвление' (или должностное лицо () производная).

Не забудьте использовать '/usr/bin/time', поскольку я не уверен, что встроенное 'время' от удара сделает ту же 'еду' сигнала.

2
27.01.2020, 19:41
  • 1
    хорошая альтернатива time с этой целью был бы env, так как все, что это делает, добавляют нуль или больше дополнительных переменных к среде программы, которую это запускает. Это не испускает собственного вывода, и код возврата вызванной программы будет пасоваться назад до любого названного env. –  James Sneeringer 06.07.2012, 20:20
  • 2
    {Хихиканье}, я думал об этом некоторое время после того, как я описываю это. Время было первой вещью, которая пришла на ум как, "выполненный что-то" управляют. Работы приятно все же. Поздравляю и спасибо. –  lornix 06.07.2012, 20:26

Ни один time ни env работавший для меня (они проводят возвращаемое значение своей дочерней программы), таким образом, я записал bliss:

#!/bin/sh
"$@"
exit 0

затем chmod u+x ~/bliss

и что-то как find_or_similar | xargs ~/bliss fatally_dying_program.sh

2
27.01.2020, 19:41

Казалось бы, один из самых очевидных разговорных выражений упоминается только в других предложениях.

То есть вы можете использовать следующее:

bash -c '$PROG_WHICH_MAY_FAIL ; (true)'

для «принудительного успеха».

Обратите внимание, это соответствует предложению lornix (только не так много слов).

В любом случае, поскольку это фактически игнорирует фактический статус завершения процесса, я бы позаботился о том, чтобы вы как-то рассмотрели возможность сохранения статуса подпроцесса для посмертного анализа. Например:

bash -c '$PROG_WHICH_MAY_FAIL || touch failed; (true)'

true здесь в некоторой степени избыточно, поэтому его лучше записать так:

bash -c '$PROG_WHICH_MAY_FAIL || touch failed'

Поскольку мы, вероятно, хотели бы знать, когда «сбойный» файл не может быть затронут. Другими словами, мы больше не игнорируем сбой, мы отмечаем и продолжаем.

И, рассмотрев рекурсивный характер этой проблемы, возможно, мы точно поймем , почему xargs не упрощает игнорирование сбоев. Потому что это никогда не бывает хорошей идеей - вместо этого вам следует улучшить обработку ошибок в процессе, который вы разрабатываете. Однако я считаю, что это понятие больше присуще самой «философии Unix».

Наконец, я полагаю, это также то, на что намекает Джеймс Янгман, рекомендуя ловушку , которую, предположительно, можно было бы использовать аналогичным образом. То есть, не игнорируйте проблему ... ловите ее и решайте, иначе вы однажды проснетесь и обнаружите, что ни одна из подпрограмм не достигла успеха; -)

9
27.01.2020, 19:41

Теги

Похожие вопросы