트랩을 사용하여 종료 확인

트랩을 사용하여 종료 확인

Ctrl+C사용자에게 확인을 요청하는 신호를 잡으려고 합니다 . 캡처 부분은 잘 작동합니다. 그러나 일단 신호가 포착되면 정상적인 실행으로 돌아가지 않습니다. 대신 스크립트를 종료합니다. 사용자가 아니오를 눌렀을 때 실행을 다시 시작하게 하려면 어떻게 해야 합니까?

이게 내 코드야

hell()
{
echo "Do you want to quit? Press 1 for yes and 0 for no";
read n;
if [ $n == 1 ]; then
exit 1;
fi
}

trap "hell" SIGINT

find /

답변1

무슨 일이에요

Ctrl+를 누르면 신호가 전체로 전달됩니다 C.SIGINT포그라운드 프로세스 그룹. 여기서는 find프로세스와 호출 쉘 프로세스 로 전송됩니다 . find반응은 즉시 종료되는 것이고, 쉘 반응은 트랩을 호출하는 것입니다.

트랩의 코드가 반환되면(즉, 호출되지 않음 exit) 신호에 의해 중단된 명령 다음에 오는 명령으로 실행이 계속됩니다. 여기서는 명령 find뒤에 스크립트가 끝나므로 어쨌든 스크립트가 즉시 종료됩니다. 그러나 다른 명령을 추가하면 입력 0과 1의 차이를 확인할 수 있습니다.

find /
echo "find returned $?"

하고 싶은 일을 하는 방법(하지만 해서는 안 될 수도 있음)

원하는 대로 할 수 있지만 내 대답의 이 부분은 실제 문제를 해결하는 것보다 쉘 프로그래밍을 발견하는 것에 관한 것입니다.

  • 설계상 재시작 가능 신호는 쉘 스크립트와 같은 상대적으로 간단한 프로그램에서 일반적으로 기대하는 신호가 아닙니다. Ctrl+가 C스크립트를 종료할 것으로 예상 됩니다.
  • 그러나 아래에서 볼 수 있듯이 이는 셸의 기능을 약간 확장합니다.

살인을 피하고 싶다면 find,배경: find / &. 그런 다음 사용wait내장정상적으로 종료될 때까지 기다립니다. 신호는 wait전파할 신호를 받을 때까지 루프에서 실행할 수 있는 내장 프로그램을 중단합니다. 그런 다음 kill.

hell () {
  echo "Do you want to quit? Press 1 for yes and 0 for no"
  read n
  if [ "$n" = 1 ]; then
    # Kill the job if it's running, then exit
    if [ -n "$job_pid" ]; then kill $job_pid; fi
    exit 1
  fi
}

job_pid=
trap "hell" SIGINT

# Start a demo job in the background
for i in 1 2 3 4 5; do date; sleep 1; done &
job_pid=$!
# Call wait in a loop; wait will return 0 if the job exits, and 128+$signum if interrupted by a signal.
while ! wait; do
  echo "resuming wait"
done
job_pid=
echo last exit code: $?

이 접근 방식에는 셸에 다음과 같은 제한 사항이 있습니다.

  • 경쟁 조건이 있습니다. 작업이 완료된 후 line 이전에 +를 누르면 Ctrl신호 처리기가 종료를 시도하지만 프로세스는 더 이상 존재하지 않습니다(심지어 수확되었으므로 좀비인 경우에도). ID가 이미 다른 프로세스에서 재사용되었을 수 있습니다. 이는 셸에서 쉽게 해결되지 않습니다(아마도 핸들러를 설정하여?).Cjob_pid=$jobpidwaitSIGCHLD
  • wait $job_pid이 양식은 일자리의 반환 상태가 필요한 경우 필요합니다 . 그러나 "신호에 의해 중단됨"과 "신호에 의해 작업이 종료됨"을 구별할 수 없습니다 wait("작업이 반환 상태 ≥ 128로 자체 종료됨"도 아니지만 이는 쉘 프로그래밍에서 일반적인 사실입니다).
  • 이는 여러 하위 작업으로 쉽게 확장되지 않습니다. 대부분의 쉘 구현의 기본을 넘어서면 트랩과 신호가 종종 놀라운 방식으로 작동한다는 점에 유의하십시오(ksh만이 이를 잘 수행합니다).

이러한 제한을 극복하려면 Perl이나 Python과 같은 고급 언어를 사용하세요.

관련 정보