Computer >> 컴퓨터 >  >> 프로그램 작성 >> BASH 프로그래밍

스크립트에서 Bash 트랩 사용

쉘 스크립트가 시작될 때 감지하기는 쉽지만 언제 중지되는지 알기가 항상 쉬운 것은 아닙니다. 스크립트는 작성자가 의도한 대로 정상적으로 종료될 수 있지만 예기치 않은 치명적인 오류로 인해 실패할 수도 있습니다. 스크립트가 실패했을 때 진행 중이던 모든 것을 그대로 유지하는 것이 좋을 때도 있고 불편할 때도 있습니다. 어느 쪽이든, 스크립트의 끝을 감지하고 미리 계산된 방식으로 이에 반응하기 때문에 Bash trap 지시문이 존재합니다.

실패 대응

다음은 스크립트에서 한 번의 실패가 어떻게 미래의 실패로 이어질 수 있는지에 대한 예입니다. /tmp에 임시 디렉토리를 생성하는 프로그램을 작성했다고 가정해 보겠습니다. 파일을 다른 형식으로 다시 묶기 전에 보관을 취소하고 처리할 수 있도록:

#!/usr/bin/env bash
CWD=`pwd`
TMP=${TMP:-/tmp/tmpdir}

## create tmp dir
mkdir "${TMP}"

## extract files to tmp
tar xf "${1}" --directory "${TMP}"

## move to tmpdir and run commands
pushd "${TMP}"
for IMG in *.jpg; do
  mogrify -verbose -flip -flop "${IMG}"
done
tar --create --file "${1%.*}".tar *.jpg

## move back to origin
popd

## bundle with bzip2
bzip2 --compress "${TMP}"/"${1%.*}".tar \
      --stdout > "${1%.*}".tbz

## clean up
/usr/bin/rm -r /tmp/tmpdir

대부분의 경우 스크립트는 예상대로 작동합니다. 그러나 예상한 JPEG 파일 대신 PNG 파일로 채워진 아카이브에서 실수로 실행하면 중간에 실패합니다. 하나의 실패는 다른 실패로 이어지며 결국 스크립트는 임시 디렉토리를 제거하라는 최종 지시에 도달하지 않고 종료됩니다. 디렉토리를 수동으로 제거하기만 하면 빠르게 복구할 수 있지만 그렇게 할 수 없다면 다음에 스크립트가 실행될 때 예측할 수 없는 남은 파일로 가득 찬 기존 임시 디렉토리를 처리해야 합니다.

이를 방지하는 한 가지 방법은 스크립트 시작 부분에 예방적 제거를 추가하여 논리를 뒤집고 이중화하는 것입니다. 유효하지만 구조 대신 무차별 대입에 의존합니다. 보다 우아한 솔루션은 trap입니다. .

트랩으로 신호 잡기

trap 키워드는 신호를 포착합니다. 실행 중에 발생할 수 있습니다. kill을 사용한 적이 있다면 이러한 신호 중 하나를 사용한 것입니다. 또는 killall SIGTERM을 호출하는 명령 기본적으로. 쉘이 응답하는 다른 많은 신호가 있으며 대부분은 trap -l 로 볼 수 있습니다. ("목록"에서와 같이):

$ trap --list
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

이러한 신호는 trap으로 예상할 수 있습니다. . 이 외에도 trap 인식:

  • EXIT :쉘 프로세스 자체가 종료될 때 발생
  • ERR :명령(예:tar 또는 mkdir ) 또는 기본 제공 명령(예:pushd 또는 cd ) 0이 아닌 상태로 완료됨
  • DEBUG :디버그 모드를 나타내는 부울

Bash에서 트랩을 설정하려면 trap을 사용하세요. 그 다음에는 실행하려는 명령 목록, 트리거할 신호 목록이 옵니다.

예를 들어, 이 트랩은 SIGINT를 감지합니다. , 사용자가 Ctrl+C를 누를 때 전송되는 신호 프로세스가 실행되는 동안:

trap "{ echo 'Terminated with Ctrl+C'; }" SIGINT

임시 디렉토리 문제가 있는 예제 스크립트는 트랩 감지 SIGINT로 수정할 수 있습니다. , 오류 및 성공적인 종료:

#!/usr/bin/env bash
CWD=`pwd`
TMP=${TMP:-/tmp/tmpdir}

trap \
 "{ /usr/bin/rm -r "${TMP}" ; exit 255; }" \
 SIGINT SIGTERM ERR EXIT

## create tmp dir
mkdir "${TMP}"
tar xf "${1}" --directory "${TMP}"

## move to tmp and run commands
pushd "${TMP}"
for IMG in *.jpg; do
  mogrify -verbose -flip -flop "${IMG}"
done
tar --create --file "${1%.*}".tar *.jpg

## move back to origin
popd

## zip tar
bzip2 --compress $TMP/"${1%.*}".tar \
      --stdout > "${1%.*}".tbz

복잡한 작업의 경우 trap을 단순화할 수 있습니다. Bash 함수가 있는 문.

Bash의 트랩

트랩은 스크립트가 성공적으로 실행되는지 여부에 관계없이 스크립트가 깔끔하게 종료되도록 하는 데 유용합니다. 자동화된 가비지 수집에 완전히 의존하는 것은 결코 안전하지 않으므로 일반적으로 사용하는 것이 좋습니다. 스크립트에서 사용해 보고 무엇을 할 수 있는지 확인하십시오!