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