bash 스크립트에서 임시 파일을 만들고 있습니다. 처리가 끝날 때 삭제하지만 스크립트가 꽤 오랫동안 실행되고 있기 때문에 실행 중에 종료하거나 CTRL-C를 실행하면 임시 파일이 삭제되지 않습니다.
실행이 끝나기 전에 이러한 이벤트를 포착하고 파일을 정리할 수있는 방법이 있습니까?
또한 해당 임시 파일의 이름과 위치에 대한 모범 사례가 있습니까?
현재 다음을 사용하는지 잘 모르겠습니다.
TMP1=`mktemp -p /tmp`
TMP2=`mktemp -p /tmp`
...
과
TMP1=/tmp/`basename $0`1.$$
TMP2=/tmp/`basename $0`2.$$
...
아니면 더 나은 해결책이 있습니까?
답변
종료 할 때 실행하도록 ” trap “을 설정 하거나 정리하기 위해 control-c에서 실행할 수 있습니다.
trap "{ rm -f $LOCKFILE; }" EXIT
또는 내가 가장 좋아하는 유닉스 리즘 중 하나는 파일을 연 다음 열려있는 동안 삭제하는 것입니다. 파일은 파일 시스템에 남아 있으며 읽고 쓸 수 있지만 프로그램이 종료되면 파일이 사라집니다. 그래도 bash에서 어떻게할지 모르겠습니다.
BTW : 자신의 솔루션을 사용하는 대신 mktemp를 선호하는 한 가지 주장 : 사용자가 프로그램이 거대한 임시 파일을 생성 할 것으로 예상하면 TMPDIR
/ var / tmp와 같이 더 큰 어딘가로 설정하고 싶을 수 있습니다 . mktemp는 손으로 굴린 솔루션 (두 번째 옵션)은 인식하지 못합니다. TMPDIR=/var/tmp gvim -d foo bar
예를 들어 나는 자주 사용 합니다.
답변
일반적으로 모든 임시 파일을 저장할 디렉터리를 만든 다음 스크립트가 종료 될 때이 디렉터리를 정리하는 EXIT 처리기를 만듭니다.
MYTMPDIR=$(mktemp -d)
trap "rm -rf $MYTMPDIR" EXIT
모든 임시 파일을 아래에두면 $MYTMPDIR
대부분의 상황에서 스크립트가 종료 될 때 모두 삭제됩니다. SIGKILL (kill -9)로 프로세스를 종료하면 프로세스가 즉시 종료되므로이 경우 EXIT 핸들러가 실행되지 않습니다.
답변
trap 명령 을 사용하여 스크립트 종료 또는 CTRL-C와 같은 신호를 처리 하려고합니다 . 자세한 내용은 Greg의 Wiki 를 참조하십시오.
basename $0
임시 파일의 경우 충분한 임시 파일을위한 공간을 제공하는 템플릿을 제공 할뿐만 아니라 사용 하는 것이 좋습니다.
tempfile() {
tempprefix=$(basename "$0")
mktemp /tmp/${tempprefix}.XXXXXX
}
TMP1=$(tempfile)
TMP2=$(tempfile)
trap 'rm -f $TMP1 $TMP2' EXIT
답변
선택한 답변은 bashism
이며 이는 다음과 같은 솔루션을 의미합니다.
trap "{ rm -f $LOCKFILE }" EXIT
bash에서만 작동합니다 (shell이 dash
또는 classic 인 경우 Ctrl + c를 잡지 못함 sh
). 호환성을 원한다면 트랩하려는 모든 신호를 열거해야합니다.
또한 스크립트가 신호 “0”(일명 EXIT)에 대한 트랩을 종료 할 때 항상 수행되어 trap
명령이 두 번 실행된다는 점에 유의하십시오 .
EXIT 신호가 있으면 모든 신호를 한 줄에 쌓지 않는 이유입니다.
더 잘 이해하려면 변경없이 다른 시스템에서 작동하는 다음 스크립트를 살펴보십시오.
#!/bin/sh
on_exit() {
echo 'Cleaning up...(remove tmp files, etc)'
}
on_preExit() {
echo
echo 'Exiting...' # Runs just before actual exit,
# shell will execute EXIT(0) after finishing this function
# that we hook also in on_exit function
exit 2
}
trap on_exit EXIT # EXIT = 0
trap on_preExit HUP INT QUIT TERM STOP PWR # 1 2 3 15 30
sleep 3 # some actual code...
exit
이 솔루션은 최종 종료 ( preExit
함수) 직전에 실제 신호 발생시 일부 코드를 실행할 수 있고 필요한 경우 실제 EXIT 신호 (종료 최종 단계)에서 일부 코드를 실행할 수 있으므로 더 많은 제어를 제공합니다.
답변
답변
tempfile
안전한 방식으로 / tmp에 파일을 생성하는 것을 선호 하며 이름 지정에 대해 걱정할 필요가 없습니다.
tmp=$(tempfile -s "your_sufix")
trap "rm -f '$tmp'" exit
답변
나는 너무 많은 사람들이 파일 이름에 공백이 없을 것이라고 생각한다고 믿을 수 없습니다. $ TMPDIR이 “임시 디렉토리”에 할당되면 세계가 충돌합니다.
zTemp=$(mktemp --tmpdir "$(basename "$0")-XXX.ps")
trap "rm -f ${zTemp@Q}" EXIT
파일 이름의 작은 따옴표 및 캐리지 리턴과 같은 공백 및 기타 특수 문자는 적절한 프로그래밍 습관의 요구 사항으로 코드에서 고려해야합니다.