다음은 현재 디렉토리에 임시 디렉토리를 설정하고 종료 시 이를 삭제하는 트랩을 설정하는 간단한 스크립트입니다.
#filename: script
set -x
trap 'rm -rf "$d"' exit
d=`TMPDIR=$PWD mktemp -d`
"$@"
ksh script sleep 100
또는 bash script sleep 100
으로 중단 하면 C-C
트랩이 실행되고 디렉토리가 삭제됩니다. 에서는 작동하지 않습니다 dash
. 왜? 이것은 버그입니까, 아니면 의도된 동작입니까?
답변1
zsh
, pdksh
(최신 버전은 아니지만 mksh
) yash
, Bourne 쉘은 dash
.
bash
, ksh88
및 만 다르게 동작 ksh93
합니다 mksh
.
SIGINT
POSIX 사양은 올바른 동작이 무엇인지 명확하지 않지만 쉘이 (또는 다른) 신호 에 대한 기본 핸들러를 재정의할 수 있다는 내용은 없습니다 .
EXIT
트랩 작업이 호출될 때 평가되어야 한다고 말하지만 AFAICT는 예를 들어 구문 오류 또는 특수 내장 실패와 같은 오류 조건 exit
의 결과로 쉘이 종료될 때 평가되어야 하는지조차 말하지 않습니다 .set -e
set -u
EXIT
신호 수신 시 트랩을 실행할 수 있으려면 쉘이 해당 신호에 핸들러를 설치해야 합니다.
그것이 바로 ksh
, mksh
그리고 bash
하는 일이지만, 그들이 처리하는 신호 목록은 세 가지 구현 모두에서 다릅니다. 3 개 모두에 공통되는 유일한 신호는 INT
, QUIT
, 및 입니다 .TERM
ALRM
HUP
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
신호의 경우에도 트랩을 실행해야 하는지 여부를 정의하지 않고 EXIT
언급한 경우 Bourne Shell이 트랩을 호출하지 않는다는 사실을 고려하면 다음을 입력하는 것이 분명합니다.불특정행동.