ksh 및 bash의 대시 대 종료 트랩

ksh 및 bash의 대시 대 종료 트랩

이것은 현재 디렉토리에 임시 디렉토리를 설정하고 종료 시 이를 삭제하도록 트랩을 설정하는 간단한 스크립트입니다.

#filename: script   
set -x  
trap 'rm -rf "$d"' exit
d=`TMPDIR=$PWD mktemp -d`
"$@"

ksh script sleep 100or 를 실행 bash script sleep 100하고 중단하면 C-C트랩이 실행되고 디렉터리가 삭제됩니다. 작동하지 않습니다 dash. 왜죠? 이것은 버그입니까, 아니면 의도적인 동작입니까?

답변1

zsh, ( pdksh최신 버전은 아니지만) Bourne 쉘은 .mkshyashdash

bash, ksh88및 기타 작업 만 가능합니다 ksh93.mksh

SIGINTPOSIX 사양에는 올바른 동작이 무엇인지 명확하지 않지만 쉘이 신호에 대한 기본 처리기를 재정의하도록 허용하는 내용은 없습니다 .

EXIT트랩 연산은 호출될 때 평가되어야 한다고 말하지만 , 내가 아는 한, 예를 들어 구문 오류나 특수 내장과 같은 오류 조건 으로 exit인해 쉘이 종료될 때 평가해야 하는지조차 말하지 않습니다. 기능 장애 시).set -eset -u

신호를 받은 후 트랩을 실행할 수 있으려면 EXIT쉘이 신호에 핸들러를 설치해야 합니다.

그것이 바로 ksh, mksh그리고 하는 일이지만, bash그들이 처리하는 신호 목록은 세 가지 구현 간에 다릅니다. 세 가지 구현 간의 유일한 공통 신호는 INT, 및 입니다 QUIT.TERMALRMHUP

EXIT특정 신호에 대해 트랩을 실행 하려는 경우 이식 가능한 접근 방식은 해당 신호를 직접 처리하는 것입니다.

trap 'exit 1' INT HUP QUIT TERM ALRM USR1
trap 'cleanup' EXIT

그러나 이 접근 방식은 작동하지 않으며 트랩 핸들러에서 호출되면 zsh트랩이 실행되지 않습니다 EXIT.exit

또한 부모님께 사망신고를 할 수도 없습니다.

따라서 다음을 수행할 수 있습니다.

for sig in INT QUIT HUP TERM ALRM USR1; do
  trap "
    cleanup
    trap - $sig EXIT
    kill -s $sig "'"$$"' "$sig"
done
trap cleanup EXIT

이제 를 실행하는 동안 더 많은 신호가 도착하면 cleanup다시 cleanup실행될 수 있습니다. cleanup작업이 여러 번 호출되거나 실행 중에 신호가 무시되는 경우 작업을 올바르게 수행하고 있는지 확인할 수 있습니다.

답변2

경고: exit작동이 보장되지는 않습니다.EXIT

POSIX 표준은 EXIT신호가 있을 때 트랩을 실행해야 하는지 여부를 정의하지 않고 Bourne Shell이 EXIT​​언급한 상황에서 트랩을 호출하지 않는다는 점을 고려하면 다음을 입력하는 것이 분명합니다.명시되지 않은행동.

관련 정보