스크립트 대상:스크립트는 ./script.sh cmd1 cmd2 ... cmdn
백그라운드에서 명령줄에서 인수로 전달된 모든 명령을 실행하고 모든 명령의 실행이 완료되었는지 확인해야 합니다. 또한 SIGTERM 신호가 스크립트로 전송되면 위의 모든 프로세스( cmd1 ... cmdn
)를 종료한 다음 자체를 종료해야 합니다.
질문:자동 종료를 제외하고는 모든 것이 작동하는 것 같은데 이유를 모르겠습니다. 을 사용해 보았지만 kill $$
런타임에 . 명령이 함수 내부에 있다는 사실과 관련이 있는 segmentation fault
것 같지만 명령을 주석 처리 하고 그대로 두면 후자가 작동합니다. 누군가 내가 놓친 것을 설명해 줄 수 있습니까?kill
kill $$
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
더 명확하게 만들 수 있습니다.