오류시 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
발생시 정의되지 않은 변수 오류 발생 및
-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이 아닌 리턴 값을 리턴 한 파이프에서 마지막 명령의 종료 상태를 리턴합니다.
첫 번째 줄에 맞는 허용되는 답변에 대한 대안 :
#!/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
되지 않습니다
.
권장 사항
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
다음과 같은 간단한 경우에는 작동하지 않습니다 (자세한 설명은 위키에서 찾을 수 있음)
- 산술 연산자
또는let
($((..))
4.1 이상)을 사용하여 변수 값을 다음과 같이 증가bash
#!/usr/bin/env bash set -e i=0 let i++ # or ((i++)) on bash 4.1 or later echo "i is $i"
- 잘못된 명령 인 경우
하지
통해 실행 한 마지막 명령의 일부
또는&&
. 예를 들어 아래 트랩은 예상대로 발사되지 않습니다.||
#!/usr/bin/env bash set -e test -d nosuchdir && echo no dir echo survived
-
명령문 에서 잘못 사용될 때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
로 설정 하지 않으면 무시됩니다.inherit_errexit
bash
#!/usr/bin/env bash set -e foo=$(expr 1-1; true) echo survived
- 당신은 다음과 같은 과제처럼 보이지만하지 않은 명령을 사용할 때
,export
,declare
또는typeset
. 이전에 설정된 오류 코드를 스윕 했기 때문에에 대한 함수 호출local
이 종료f
되지 않습니다
.local
set -e f() { local var=$(somecommand that fails); } g() { local var; var=$(somecommand that fails); }
- 파이프 라인에서 사용될 때 문제가되는 명령은 마지막 명령의 일부 가
아닙니다
. 예를 들어 아래 명령은 여전히 진행됩니다. 한 가지 옵션은 첫 번째 실패한 프로세스
의 종료 코드를 리턴하여 사용 하는 것입니다.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
도움이 되겠다면 ↓↓↓ 배너 한번만 클릭 해주시면 감사합니다 ^^
'programing' 카테고리의 다른 글
파이썬의 디렉토리 트리 목록 (0) | 2020.02.09 |
---|---|
Perl에서 로케일 설정 경고를 수정하는 방법? (0) | 2020.02.09 |
OAuth 2는 보안 토큰을 사용한 재생 공격과 같은 것들로부터 어떻게 보호합니까? (0) | 2020.02.09 |
배열 대 목록 (0) | 2020.02.09 |
클라이언트가 JavaScript 파일을 새로 고치도록하려면 어떻게해야합니까? (0) | 2020.02.09 |