때로는 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
(여기 )을 지정한 후에는 주의하세요.fnord
seq
답변4
time
둘 다 나에게 맞지 않아서 env
(서브루틴의 반환 값을 전달함) 다음과 같이 썼습니다 bliss
.
#!/bin/sh
"$@"
exit 0
그 다음에chmod u+x ~/bliss
그리고 비슷한 것들find_or_similar | xargs ~/bliss fatally_dying_program.sh