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