`xargs`가 하위 종료를 무시하고 추가 처리를 계속하도록 만드는 방법

`xargs`가 하위 종료를 무시하고 추가 처리를 계속하도록 만드는 방법

나는 때때로 밤새도록 긴 작업을 수행하는데 , 예를 들어 오늘 밤에 일어난 것처럼 하나의 특별한 경우에서 분할 오류로 인해 중간 어딘가에서 죽은 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하위 프로세스가 종료되면 더 이상 입력 처리를 중지하지 않고 대신 처리를 계속할 수 있습니까 ?

답변1

아니요, 그럴 수 없습니다. 로부터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 메이크:

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

all: $(TARGETS)

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

그 다음에:

$ make -k -j4 

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

답변2

가장 명백한 구어체 중 하나는 다른 제안에 의해서만 암시되는 것 같습니다.

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

bash -c '$PROG_WHICH_MAY_FAIL ; (true)'

"성공을 강요"하기 위해.

참고로 이는 제안서의 내용과 일치합니다.로닉스(너무 많은 말로는 아닙니다).

어쨌든 이는 실제 프로세스 종료 상태를 효과적으로 무시하므로 사후 분석을 위해 하위 프로세스 상태를 어떻게든 저장하는 것을 고려해 보시기 바랍니다. 예:

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

여기 true에는 다소 중복되므로 다음과 같이 작성하는 것이 더 좋습니다.

bash -c '$PROG_WHICH_MAY_FAIL || touch failed'

왜냐하면 우리는 '실패한' 파일을 언제 건드릴 수 없는지 알고 싶을 것이기 때문입니다. 즉, 우리는 더 이상묵살실패에 대해 주목하고 계속 진행하고 있습니다.

그리고 이 문제의 반복적 성격을 고려한 후에 아마도 우리는 정확히 알 수 있을 것입니다.xargs는 실패를 무시하는 것을 쉽게 만들지 않습니다. 이는 결코 좋은 생각이 아니기 때문에 대신 개발 중인 프로세스 내에서 오류 처리를 강화해야 합니다. 그러나 나는 이 개념이 "유닉스 철학" 자체에 더 내재되어 있다고 믿습니다.

마지막으로 James Youngman이 을 추천하면서 암시한 내용이기도 한데 trap, 이는 아마도 유사한 방식으로 사용될 수 있을 것입니다. 즉, 문제를 무시하지 마십시오... 문제를 가두어 처리하거나 어느 날 깨어났을 때 하위 프로그램 중 어느 것도 전혀 성공하지 못했다는 것을 알게 됩니다 ;-)

답변3

사용 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..값을 지정해야 한다는 점에도 유의하세요 .$0fnordseq

답변4

나에게도 도움이 되지 않았 으므로(자식 프로그램의 반환 값을 전달함) 다음 timeenv같이 썼습니다 bliss.

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

그 다음에chmod u+x ~/bliss

그리고 뭔가find_or_similar | xargs ~/bliss fatally_dying_program.sh

관련 정보