생성 된 자식 프로세스가 실패하면 모두 종료하고 종료하십시오.


9

내 스크립트에서 데이터 세트를 input_aa, input_ab 등으로 나누었습니다. 그런 다음 각각 동일한 Python 스크립트를 통해 실행합니다.

# Execute program on each split file
for part in input_*; do
        python3 $part &
done
wait

내 질문은 두 가지입니다 : 파이썬 프로세스가 실패했다는 것을 어떻게 감지합니까? 그리고 감지되면, 생성 된 모든 자식을 죽이고 실패로 스크립트를 종료하는 방법은 무엇입니까?

답변:


10

프로세스 그룹을 사용할 수 있습니다.

set -m
(
   for part in input_*; do
     (python3 "$part" || kill 0) &
   done
   wait
)

set -m(및 선택적 POSIX 셸 기능, 필수 Unix 셸 기능)은 자체 프로세스 그룹에서 작업을 실행합니다. 에서 bash, yash, zsh, mksh상기 하부 쉘의 작업 있다는 set -m외측되도록 설정되어 (...), 그 내에 생성 된 모든 프로세스는 동일한 프로세스 그룹에 배치 될 것이다.

들어 dash및 기타 ash기반 쉘, 그에만 최상위 쉘 프로세스에서 작동합니다. 따라서 해당 코드는 서브 쉘에 넣지 않으면 작동합니다.

AT & T ksh또는 이전 SysV / Bourne 셸에서는 전혀 작동하지 않습니다 .

kill 0 현재 프로세스 그룹의 모든 멤버에게 SIGTERM 신호를 보냅니다.


bash에서. 내가 shebang을 포함시킨 이유-필요한 껍질이 명확하지 않습니다. 좋은 답변
jim mcnamara

@jimmcnamara에서 작동하는지 bash, dash, yash, mksh, zsh. 기본적으로 모든 POSIX 쉘이지만 AT & T ksh. set -mPOSIX에서 (미만) 지정되지만 선택적 기능입니다.
Stéphane Chazelas

솔라리스를 사용합니다. / bin / sh는 비행하지 않습니다.
jim mcnamara

@jimmcnamara, Solaris 10 이전 버전에서는 / bin / sh가없고 Bourne 쉘 (POSIX 쉘 아님)이며 11 일에는 AT & T ksh입니다. 내가 말했듯이 bash, dash, yash, mksh, zsh에서 작동합니다.
Stéphane Chazelas

1
@ mikeserv는 프로세스를 1로 다시 지정하지만 프로세스 그룹에서 제거하지는 않습니다. kill 0부모가 무엇이든 프로세스 그룹의 모든 구성원을 종료합니다. 참조 ps -j프로세스 그룹 ID를 볼 수 있습니다.
Stéphane Chazelas

3

이것은 예입니다. 필요한 것을 정확하게 얻으려면 먼저이 게임을하십시오. 그대로 깨뜨릴 수 없습니다.

#!/bin/bash
# Example of killing off all children

> killfile
> outfile.err
kill_em()
{
   echo 'killing all children ' > 2
   while read pid
   do
      kill -0 $pid && kill -9 $pid  # if still running kill it
   done < killfile
   exit 1
}

export grandparentpid=$$
trap 'kill_em' 6
for i in 2 2 3 4 5 6 7 8 9 10
do
        ( sleep $i && ls oinkle  >> outfile 2>> outfile.err &
          pid=$!
          echo $pid >> killfile
          wait $!
          [ $? -ne 0 ] && kill -6 $grandparentpid
        ) &
done
wait

ls oinkle내 컴퓨터에서 실패 하기 때문에 의도적으로 실패하도록 설정되었습니다 .

스타터 스크립트로 땜질 후 필요한 것을 얻으면 --- 변경 :

for i in 2 2 3 4 5 6 7 8 9 10

에:

for part in input_* 

변화:

sleep $i && ls oinkle 

에:

python3 $part 

리디렉션은 로그를 저장하기 위해 존재합니다. 당신은 그들을 원하지 않을 수 있습니다.


좀 비열합니다. 다른 모든 작업이 시작되기 전에 작업 중 하나가 실패하면 시작된 killfile작업의 모든 pid를 포함하지 않을 수 있습니다.
Stéphane Chazelas

같은 몇 가지 나쁜 관행 : 인용 부호로 둘러싸이지 않은 변수, 신호 번호 대신 이름의 사용, 사용 신호 (6) (ABRT 예를 들어 리눅스 AMD64에서) 사용자 신호로 대신 USR1 / USR2의, [ $? -ne 0 ]...
스테판 Chazelas가
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.