‘xargs’가 자식의 종료를 무시하고 계속 처리하는 방법 : [09:35:48] %

나는 때때로 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자식 프로세스가 종료되고 대신 처리를 계속하면 더 이상 입력을 처리하지 못하게 할 수 있습니까 ?



답변

아냐, 못해 xargssavannah.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;

해당 검사 또는 호출하는 함수 주위에 플래그가 없습니다. max procs와 관련이있는 것 같습니다. 이것이 의미가 있다고 생각합니다 .max procs를 충분히 높게 설정하면 한계에 도달 할 때까지 확인하지 않아도됩니다.

당신이하려는 일에 대한 더 나은 해결책은 GNU Make 를 사용하는 것일 수 있습니다 .

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

all: $(TARGETS)

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

그때:

$ make -k -j4

동일한 효과가 있으며 훨씬 더 나은 제어 기능을 제공합니다.


답변

그것은 가장 명백한 구어체 중 하나가 다른 제안에 의해서만 언급되는 것처럼 보일 것입니다.

즉, 다음을 사용할 수 있습니다.

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 철학”자체에 더 내재되어 있다고 생각합니다.

마지막으로, 나는 이것이 trap비슷한 방식으로 사용될 수 있다고 James Youngman이 추천함으로써 암시하는 것이라고 생각합니다. 즉, 문제를 무시하지 마십시오 … 문제를 포착하고 처리하거나 언젠가 일어나서 하위 프로그램 중 아무것도 성공하지 못했음을 발견하십시오. 😉


답변

사용 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.


답변

죽어가는 프로그램의 신호를 ‘먹는’다른 명령을 넣으십시오.

나는 문제를 증명하기 위해 처음에 당신의 예제를 시도했습니다 … ‘killall sleep’은 수면 프로세스를 죽이고 bash를 중단하고 xargs는 종료됩니다.

테스트로, xargs와 bash 사이에 ‘Run another command’유형 명령을 사용했습니다 …이 경우 ‘/ usr / bin / time’. 이번에는 (말장난 없음) killall sleep이 절전 프로세스를 종료하지만 xargs는 계속 진행됩니다.

시간 출력을 / dev / null로 파이프하면 기존 프로세스를 크게 다시 작성하지 않고도 원하는 결과를 정확하게 얻을 수 있습니다.

나는 잠시 동안 숙고하면 ‘/ usr / bin / time’에서 stderr chatter없이 동일한 작업을 수행 할 수있는 다른 프로그램을 생각해 낼 수 있다고 생각합니다. 또는 직접 작성해도 ‘포크'(또는 exec () 파생물) 일뿐입니다.

bash의 내장 ‘시간’이 신호의 동일한 ‘먹음’을 수행하는지 확실하지 않으므로 ‘/ usr / bin / time’을 사용하십시오.


답변

나는 나를 위해 일 하지도 time않았고 env(자녀 프로그램의 반환 가치를 전달 하지 않음 ) 나는 썼다 bliss.

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

그때 chmod u+x ~/bliss

그리고 같은 find_or_similar | xargs ~/bliss fatally_dying_program.sh


답변