신호 처리기로 스스로를 종료하는 스크립트가 분할 오류를 생성하는 이유는 무엇입니까?

신호 처리기로 스스로를 종료하는 스크립트가 분할 오류를 생성하는 이유는 무엇입니까?

스크립트 대상:스크립트는 ./script.sh cmd1 cmd2 ... cmdn백그라운드에서 명령줄에서 인수로 전달된 모든 명령을 실행하고 모든 명령의 실행이 완료되었는지 확인해야 합니다. 또한 SIGTERM 신호가 스크립트로 전송되면 위의 모든 프로세스( cmd1 ... cmdn)를 종료한 다음 자체를 종료해야 합니다.

질문:자동 종료를 제외하고는 모든 것이 작동하는 것 같은데 이유를 모르겠습니다. 을 사용해 보았지만 kill $$런타임에 . 명령이 함수 내부에 있다는 사실과 관련이 있는 segmentation fault것 같지만 명령을 주석 처리 하고 그대로 두면 후자가 작동합니다. 누군가 내가 놓친 것을 설명해 줄 수 있습니까?killkill $$kill ${PIDAR[*]}

#!/bin/bash                                                            

# signal handler                                                       
killemall () {                                                         
   echo $$                                                             
   kill ${PIDAR[*]}                                                  
   kill $$   # implicated line                                                           

}                                                                      
PIDAR=() # pid array                                                   
STAR=() # process state array                                          

# execute processes in bg and save their pid                           
for i in "$@" ; do                                                     
    $i &                                                               
    PIDAR+=($!)                                                
done                                                                   

trap 'killemall' SIGTERM                                               

terminated=1  # flag to indicate when all processes are terminated     
while  sleep 1  && [ $terminated -eq 1 ]; do                           
   for (( i=0; i<${#PIDAR[*]}; i++ )); do                              
      STAR[$i]=$(ps hp ${PIDAR[$i]} | awk '{ print $3 }')              
      if [ -z ${STAR[$i]} ]; then                                      
         terminated=0                                                  
      else terminated=1                                                
      fi         
      echo "Process state ${PIDAR[$i]}:${STAR[$i]}" | tee -a logg  
   done                                                            
done                                                               

echo "All processes are terminated"  

감사해요

해결책:user18197이 지적했듯이 문제는 kill $$실제로 kill매뉴얼 페이지에 보고된 대로 호출에 있습니다.

Kill의 기본 신호는 TERM입니다.

그런 다음 kill $$호출할 때마다 스크립트는 핸들러를 호출하고 killemall핸들러는 반복적으로 호출하는 kill $$등의 작업을 수행합니다. 이 동작을 방지하기 위해 SIGTERM신호를 포착할 수 있습니다. 보고서 에 따르면 help trap:

ARG가 없거나(단일 SIGNAL_SPEC이 제공됨) '-'인 경우 지정된 각 신호는 원래 값으로 재설정됩니다.

따라서 새로운 함수 본문은 다음과 같습니다.

killemall () {     
   echo $$
   trap - SIGTERM
   kill ${PIDAR[@]}
   kill $$                
} 

답변1

세그먼트 오류를 ​​재현할 수는 없지만 SIGTERM을 나 자신에게 보내면 Killemall 함수를 다시 호출하고 SIGTERM을 보내 Killemall을 호출할 것으로 추측됩니다...

실제로 스크립트를 종료하기 위해 어떤 작업도 수행할 필요가 없습니다. 함수 killemall가 호출되고 완료되면 스크립트가 종료됩니다. 필요한 경우 함수 끝에 추가하여 exit 0더 명확하게 만들 수 있습니다.

관련 정보