문제

Bash 스크립트에서 임시 파일을 생성 중입니다.처리가 끝나면 삭제하려고 하는데 스크립트가 꽤 오랫동안 실행 중이기 때문에 실행 중에 스크립트를 종료하거나 간단히 CTRL-C를 누르면 임시 파일이 삭제되지 않습니다.
실행이 끝나기 전에 해당 이벤트를 포착하고 파일을 정리할 수 있는 방법이 있습니까?

또한 해당 임시 파일의 이름과 위치에 대한 모범 사례가 있습니까?
현재 다음을 사용할지 확실하지 않습니다.

TMP1=`mktemp -p /tmp`
TMP2=`mktemp -p /tmp`
...

그리고

TMP1=/tmp/`basename $0`1.$$
TMP2=/tmp/`basename $0`2.$$
...

아니면 더 나은 해결책이 있을까요?

도움이 되었습니까?

해결책

당신은 ""출구 또는 Control-C에서 실행하여 청소.

trap "{ rm -f $LOCKFILE; }" EXIT

또는 제가 가장 좋아하는 Unix-Irism 중 하나는 파일을 열고 여전히 열리는 동안 삭제하는 것입니다. 파일은 파일 시스템에 유지되며 읽고 쓸 수 있지만 프로그램이 종료 되 자마자 파일이 사라집니다. 그러나 Bash에서 어떻게 할 것인지 잘 모르겠습니다.

BTW : 한 가지 논쟁은 자신의 솔루션을 사용하는 대신 MKTEMP에 찬성 할 것입니다. 사용자가 귀하의 프로그램이 거대한 임시 파일을 생성 할 것으로 예상하면, 그는 설정을 원할 수 있습니다. TMPDIR /var /tmp와 같은 더 큰 곳으로. MKTEMP는 손으로 롤링 된 솔루션 (두 번째 옵션)이 그렇지 않다는 것을 인식합니다. 나는 자주 사용합니다 TMPDIR=/var/tmp gvim -d foo bar, 예를 들어.

다른 팁

나는 일반적으로 모든 임시 파일을 배치 할 수있는 디렉토리를 만듭니다. 그리고 직후에 스크립트가 종료 될 때이 디렉토리를 정리하기 위해 종료 처리기를 작성합니다.

MYTMPDIR=$(mktemp -d)
trap "rm -rf $MYTMPDIR" EXIT

모든 임시 파일을 아래에 놓으면 $MYTMPDIR, 그러면 대부분의 상황에서 스크립트가 종료되면 모두 삭제됩니다. Sigkill (Kill -9)으로 프로세스를 죽이면 프로세스가 즉시 죽이므로 출구 핸들러 가이 경우에 실행되지 않습니다.

당신은 사용하고 싶습니다 CTRL-C와 같은 스크립트 또는 신호를 종료하도록 명령. 참조 그렉의 위키 자세한 내용은.

당신의 템 파일을 위해, 사용 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에서만 작동합니다(쉘이 다음과 같은 경우 Ctrl+c를 잡지 못합니다). dash 또는 클래식 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 신호(종료의 마지막 단계)에서 일부 코드를 실행할 수 있습니다.

$$와 함께 예측 가능한 파일 이름을 사용하는 대안은 격차 보안 구멍이므로 절대로 사용하는 것에 대해 생각해서는 안됩니다. 단일 사용자 PC의 간단한 개인 스크립트 일지라도. 당신이 얻지 말아야 할 매우 나쁜 습관입니다. Bugtraq "불안한 온도 파일"사건으로 가득합니다. 보다 여기, 여기 그리고 여기 임시 파일의 보안 측면에 대한 자세한 내용은

처음에는 불안한 TMP1 및 TMP2 과제를 인용 할 생각 이었지만 아마도 두 번째 생각은 아마도 좋은 생각이 아닙니다.

나는 사용하는 것을 선호한다 tempfile 안전한 방식으로 /TMP에 파일을 생성하고 이름 지정에 대해 걱정할 필요가 없습니다.

tmp=$(tempfile -s "your_sufix")
trap "rm -f '$tmp'" exit

MKTEMP로 생성 된 TMP 파일을 제거하는 것을 귀찮게 할 필요는 없습니다. 어쨌든 그들은 나중에 삭제됩니다.

더 고유 한 파일을 생성 할 수 있으므로 '$$'접두사를 생성 할 수 있으므로 mktemp를 사용하십시오. 또한 임시 파일을 작성한 다음 /TMP에 명시 적으로 넣는 더 많은 크로스 플랫폼 방법처럼 보입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top