"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

아니 당신은 할 수 없습니다. ~에서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;

이 검사나 이를 호출하는 함수에는 플래그가 없습니다. 이것은 max-processes와 관련이 있는 것 같습니다. 내 생각에는 이치에 맞습니다. max-processes를 충분히 높게 설정하면 한계에 도달할 때까지 확인하지 않으며 아마도 한계에 도달하지 않을 것입니다.

당신이하고 싶은 일에 대해 더 나은 해결책은 다음과 같습니다.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는 실패를 쉽게 무시하지 않습니다. 이는 결코 좋은 생각이 아니기 때문에 개발 중인 프로세스에서 오류 처리를 강화해야 합니다. 그러나 나는 이 개념이 "유닉스 철학" 자체에 더 본질적으로 있다고 믿습니다.

trap마지막으로 James Youngman 이 아마도 비슷한 방식으로 사용될 수 있다고 권고하면서 이것이 암시한 것이라고 생각합니다 . 즉, 문제를 무시하지 마십시오...그 문제를 잡아 처리하십시오. 그렇지 않으면 어느 날 깨어나서 서브루틴 중 어느 것도 성공하지 못할 것입니다 ;-)

답변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..가져와야 하는 값 $0(여기 )을 지정한 후에는 주의하세요.fnordseq

답변4

time둘 다 나에게 맞지 않아서 env(서브루틴의 반환 값을 전달함) 다음과 같이 썼습니다 bliss.

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

그 다음에chmod u+x ~/bliss

그리고 비슷한 것들find_or_similar | xargs ~/bliss fatally_dying_program.sh

관련 정보