programing

오류 발생 시 Bash 셸 스크립트에서 자동으로 종료

minimums 2023. 6. 7. 22:26
반응형

오류 발생 시 Bash 셸 스크립트에서 자동으로 종료

저는 셸 스크립트를 작성하고 있는데 명령 중 하나가 실패할 경우 해당 셸 스크립트의 실행을 중지할 수 있는 기능이 있다면 유용할 것입니다.예는 아래를 참조하십시오.

#!/bin/bash

cd some_dir

./configure --some-flags

make

make install

따라서 이 경우 스크립트가 지정된 디렉토리로 변경할 수 없는 경우 스크립트가 실패하더라도 나중에 ./configure를 수행하지 않을 것입니다.

이제 각 명령에 대해 if 검사를 수행할 수 있다는 것을 잘 알고 있습니다(이것은 가망이 없는 해결책이라고 생각합니다). 하지만 명령 중 하나가 실패할 경우 스크립트를 종료하도록 글로벌 설정이 있습니까?

기본 제공 기능 사용:

#!/bin/bash
set -e
# Any subsequent(*) commands which fail will cause the shell script to exit immediately

또는 통과할 수 있습니다.-e명령줄에서:

bash -e my_script.sh

다음을 사용하여 이 동작을 사용하지 않도록 설정할 수도 있습니다.set +e.

당신은 또한 전체 또는 일부를 고용하기를 원할 수 있습니다.-e -u -x그리고.-o pipefail다음과 같은 옵션:

set -euxo pipefail

-e오류 발생 시 종료됩니다.-u정의되지 않은 변수에 대한 오류,-x실행 전에 명령을 인쇄합니다.-o (for option) pipefail명령 파이프 오류 시 종료됩니다.일부 gotchas 및 해결 방법은 여기에 잘 문서화되어 있습니다.

(*) 참고:

실패한 명령어가 잠시 후 또는 키워드가 될 때까지 명령어 목록의 일부, if 또는 ellif 예약 단어의 일부, && 또는 || 목록에서 실행된 명령어의 일부, 마지막 && 또는 || 뒤에 이어지는 명령어를 제외한 파이프라인의 모든 명령어의 일부인 경우 셸이 종료되지 않습니다.또는 명령의 반환 값이 !로 반전되는 경우.

(부터)man bash)

명령 중 하나가 실패하는 즉시 스크립트를 종료하려면 처음에 다음을 추가합니다.

set -e

이로 인해 테스트의 일부가 아닌 명령이 실행되면 스크립트가 즉시 종료됩니다(예:if [ ... ]조건 또는&&종료 코드가 0이 아닌 종료 코드를 사용하여 종료합니다.

와 함께 사용합니다.pipefail.

set -e
set -o pipefail

-e(출구 오류):명령이 0이 아닌 상태로 종료되는 경우 첫 번째 오류 시 스크립트 중단(루프할 때까지 또는 루프할 때, if-tests 및 list constructs 제외)

-o 파이프 고장:파이프라인이 0이 아닌 반환 값을 반환한 파이프의 마지막 명령의 종료 상태를 반환하도록 합니다.

33장.옵션들

방법은 다음과 같습니다.

#!/bin/sh

abort()
{
    echo >&2 '
***************
*** ABORTED ***
***************
'
    echo "An error occurred. Exiting..." >&2
    exit 1
}

trap 'abort' 0

set -e

# Add your script below....
# If an error occurs, the abort() function will be called.
#----------------------------------------------------------
# ===> Your script goes here
# Done!
trap : 0

echo >&2 '
************
*** DONE *** 
************
'

첫 번째 줄에 맞는 허용된 답변에 대한 대안:

#!/bin/bash -e

cd some_dir  

./configure --some-flags  

make  

make install

한 가지 관용구는 다음과 같습니다.

cd some_dir && ./configure --some-flags && make && make install

시간이 오래 걸릴 수 있다는 것은 알지만, 더 큰 스크립트의 경우 논리적 기능으로 나눌 수 있습니다.

제 생각에 당신이 찾고 있는 것은trap명령:

trap command signal [signal ...]

자세한 내용은 이 페이지를 참조하십시오.

다른 옵션은 다음을 사용하는 것입니다.set -e스크립트의 맨 위에 있는 명령 - 프로그램/명령이 true가 아닌 값을 반환하는 경우 스크립트는 스크립트를 종료합니다.

기존 답변에서 누락된 한 가지 점은 오류 트랩을 상속하는 방법을 보여주는 것입니다.bash은 이러옵한중제하공다니합나를션셸을 사용하는 중 합니다.set

-E

있는 경우, 경모된트랩에 있는 ERR셸 함수, 명령 대체 및 하위 셸 환경에서 실행되는 명령에 의해 상속됩니다.ERR이러한 경우 트랩은 일반적으로 상속되지 않습니다.


Adam Rosenfield의 사용할 답변 권장 사항set -e특정한 경우에는 옳지만 잠재적인 함정이 있습니다.GreyCat의 BashFAQ - 105 - set -e(또는 set -orrexit 또는 트랩 ERR)를 참조하십시오.

설명서에 따르면 set -e exit는

단순 명령이 0이 아닌 상태로 종료되는 경우실패한 명령어가 또는 키워드 바로 뒤에 있는 명령어 목록, 의 일부, 또는 목록의 일부이거나, 또는 뒤에 있는 명령어를 제외하고 또는 명령어의 반환 값이 "를 통해 반전된 경우 셸이 종료되지 않습니다.

말은, 말은그은.set -e다음과 같은 간단한 경우에는 작동하지 않습니다(위키에서 자세한 설명을 찾을 수 있습니다).

  1. 연산자 술산 사용자산 사용let또는$((..))(bash 이후)을 4.1로 시킵니다.

    #!/usr/bin/env bash
    set -e
    i=0
    let i++                   # or ((i++)) on bash 4.1 or later
    echo "i is $i" 
    
  2. 위반 명령이 다음을 통해 실행된 마지막 명령의 일부가 아닌 경우&&또는||를 들어,의 트랩은 되지 않습니다.

    #!/usr/bin/env bash
    set -e
    test -d nosuchdir && echo no dir
    echo survived
    
  3. 못사경우된에 잘못 되었을 때if 장문as의 , 종료코드if문은 마지막으로 실행된 명령의 종료 코드입니다.가 " 아예에서마으로실명같다습니다과음은령된"였습니다.echo그것은 함정을 발사하지 않을 것이다, 비록.test -d

    #!/usr/bin/env bash
    set -e
    f() { if test -d nosuchdir; then echo no dir; fi; }
    f 
    echo survived
    
  4. 와 함께에는 " " " " 를 사용하지 않으면됩니다.inherit_errexit는 로설됩다니로 됩니다.bash 4.4

    #!/usr/bin/env bash
    set -e
    foo=$(expr 1-1; true)
    echo survived
    
  5. 다음과 같이 할당처럼 보이지만 그렇지 않은 명령을 사용하는 경우export,declare,typeset또는local은 함호있다습니이출여기수에▁here입니다.f종료되지 않음local이전에 설정한 오류 코드를 삭제했습니다.

    set -e
    f() { local var=$(somecommand that fails); }        
    g() { local var; var=$(somecommand that fails); }
    
  6. 파이프라인에서 사용되는 경우 위반 명령은 마지막 명령의 일부가 아닙니다.예를 들어, 아래 명령은 계속 수행됩니다.한 가지 옵션은 다음을 활성화입니다.pipefail번째 실패한 프로세스의 종료 코드를 반환합니다.

    set -e
    somecommand that fails | cat -
    echo survived
    

를 사용하지 않는 이 가장 좋습니다.set -e오류 검사의 자체 버전을 대신 구현합니다.Bash 스크립트에서 오류 발생에 대한 답변 중 하나에 대한 사용자 지정 오류 처리 구현에 대한 자세한 내용

언급URL : https://stackoverflow.com/questions/2870992/automatic-exit-from-bash-shell-script-on-error

반응형