programing

오류시 bash 쉘 스크립트에서 자동 종료

new-time 2020. 2. 9. 19:56
반응형

오류시 bash 쉘 스크립트에서 자동 종료


나는 일부 쉘 스크립트를 작성해 왔으며 명령 중 하나라도 실패하면 해당 쉘 스크립트의 실행을 중지하는 기능이 있으면 유용하다는 것을 알았습니다. 예를 들어 아래를 참조하십시오.

#!/bin/bash   cd some_dir   ./configure --some-flags   make   make install 

따라서이 경우 스크립트가 표시된 디렉토리로 변경할 수 없으면 실패한 경우 나중에 ./configure를 수행하지 않을 것입니다.이제 각 명령에 대해 if 검사를 수행 할 수 있다는 것을 잘 알고 있습니다 (바람직한 해결책이라고 생각합니다). 명령 중 하나가 실패하면 스크립트를 종료하도록 전역 설정이 있습니까?


 

set -e

내장을 사용하십시오 .

#!/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

발생시 정의되지 않은 변수 오류 발생 및

-o (for option) pipefail

명령 파이프 오류 발생시 종료됩니다. 몇 가지 문제와 해결 방법이

여기에

잘 설명되어 있습니다 .(*) 노트:

쉘은 수행

되지

출구 실패 명령이 즉시 다음 명령 목록의 일부인 경우

동안

이나

때까지

, 시험의 일부가 다음과 같은 키워드를

하는 경우

또는

ELIF

예약어는 어떤 A의 실행 된 명령의 일부

&&

||

마지막

&&

또는

||

뒤에 나오는 명령을 제외한리스트 , 파이프 라인의 명령이지만 마지막 명령이거나 명령의 반환 값이 ! 로 반전 된 경우

(에서

man bash

)


명령 중 하나가 실패하자마자 스크립트를 종료하려면 처음에 다음을 추가하십시오.

set -e 

이로 인해 테스트의 일부가 아닌 일부 명령 (

if [ ... ]

조건 또는

&&

구성 과 같은 )이 0이 아닌 종료 코드 로 종료되면 스크립트가 즉시 종료됩니다.


방법은 다음과 같습니다.

#!/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 ***  ************ ' 

와 함께 사용하십시오

pipefail

.

set -e set -o pipefail 

-e (errexit) : 명령이 0이 아닌 상태로 종료 될 때 첫 번째 오류 발생시 스크립트 중단 (루트 또는 while 루프, if-tests, list 구문 제외)-o pipefail : 파이프 라인이 0이 아닌 리턴 값을 리턴 한 파이프에서 마지막 명령의 종료 상태를 리턴합니다.

33 장. 옵션


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

#!/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

-이자형설정된 경우 트랩

ERR

기능은 쉘 기능, 명령 대체 및 서브 쉘 환경에서 실행되는 명령에 의해 상속됩니다. 이러한 경우

ERR

트랩은 일반적으로 상속

되지 않습니다

.


Adam Rosenfield의 답변

권장 사항

set -e

은 특정 경우에 맞지만 자체 잠재적 인 함정이 있습니다. 참조

GreyCat의 BashFAQ - 105 -하지 않는 이유는 세트 -e (또는 -o errexit, 또는 트랩 ERR 설정) 나는 무엇을 기대 하는가?

매뉴얼에 따라 set -e exits

간단한 명령이 0이 아닌 상태로 종료되는 경우 실패한 명령이 ,, 다음에 나오는 명령을 제외하고

while

또는

until

키워드 바로 다음에있는 명령 목록의 일부 이거나 , 다음에 나오는 명령을 제외한

test in a if statement

일부

&&

또는

||

목록의 일부 이거나 " 를 통해 명령의 반환 값이 반전되는 경우 쉘이 종료되지 않습니다 .

final && or ||

any command in a pipeline but the last

!

즉,

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

    명령문 에서 잘못 사용될 때

    if

    명령문의 종료 코드는 마지막으로 실행 된 명령의 종료 코드입니다. 아래 예제에서 마지막으로 실행 된 명령은 실패

    echo

    하더라도 트랩을 실행 하지 않는 명령입니다

    test -d

    #!/usr/bin/env bash set -e f() { if test -d nosuchdir; then echo no dir; fi; } f  echo survived 
  4. 명령 대체와 함께 사용되는 경우 4.4

    inherit_errexit

    로 설정 하지 않으면 무시됩니다.

    bash

    #!/usr/bin/env bash set -e foo=$(expr 1-1; true) echo survived 
  5. 당신은 다음과 같은 과제처럼 보이지만하지 않은 명령을 사용할 때

    export

    ,

    declare

    ,

    typeset

    또는

    local

    . 이전에 설정된 오류 코드를 스윕 했기 때문에에 대한 함수 호출

    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



도움이 되겠다면 ↓↓↓ 배너 한번만 클릭 해주시면 감사합니다 ^^

반응형