조건이 실패 할 때 bash 스크립트를 중지하는 방법은 무엇입니까?


11

다음 은 명령 실행을 연결 하기 위해 ||and &&를 한 줄로 사용하는 방법을 보여줍니다 . bash 스크립트에서 apt-get 오류를 어떻게 확인할 수 있습니까?

특정 조건이 실패하면 스크립트 실행을 중지하려고합니다.

예 :

false || echo "Obvious error because its false on left" && exit

여기에서 Obvious error because its false on the left내가 원하는 콘솔을 인쇄 하고 종료합니다.

true || echo "This shouldn't print" && exit

여기에는 에코 인쇄가 없지만 exit명령도 실행됩니다. 즉, 콘솔이 닫혀 exit있습니다. 오른쪽의 에코 명령이 실행되지 않아서 명령이 실행되지 않아야합니까? 아니면 기본적으로 &&연산자 의 왼쪽에서 진술이 거짓으로 간주 됩니까?

편집 : 전에 그것을 언급 했어야합니다. 제 목표는 오류를 반향하고 명확하지 않은 경우 종료하는 것이 었습니다. && 및 ||를 사용하여 조건을 그룹화 할 때 오류를 잡는 특정 사례에 대해 @ bodhi.zazen 답변이 문제를 해결합니다.

@takatakatek 답변은 흐름 제어에 대해 더 명확하게하고 bash 가이드 링크는 우수합니다.

@muru answer에는 set -e를 사용하지 않는 이유에 대한 좋은 설명이 있습니다 .Perl 및 trap을 사용하는 대안으로 사용자 정의 오류 메시지를 표시하려면 더 강력한 방법이라고 생각하고 두 번째 bash 스크립트에서 사용하십시오.


내가 알 수있는 한 스크립트가 완료되면 종료됩니다.
Panther

답변:


10

당신은 아마 원할 것입니다 (스틸 드라이버가 지적한대로)

true || { echo "This shouldn't print" && exit; }

그렇지 않으면 스크립트가 한 번에 하나의 조건부 읽기

a 또는 b 다음 종료

나는 당신이 또는 (b와 exit)를 원한다고 생각합니까?


4
사실, 당신은 해야한다 사용 { ... ; }(@steeldriver가 제안), 그렇지 않으면이 exit단지 서브 쉘을 종료하고, 부모 쉘 스크립트를 실행을 계속.
Gordon Davisson 2016 년

14

문제는 || &&는 조건이 실패 할 때 명령 체인의 하나의 후속 스탠자 만 건너 뜁니다. 전체 블록 구조를 작성하면 완벽하게 이해됩니다. 작성한 내용은 다음과 같습니다.

if ! true ; then
   echo "This shouldn't print"
else
   exit
fi

당신이 원하는 것은 이것입니다 :

if ! true ; then
   echo "This shouldn't print"
   exit
fi

Bash의 바로 가기 조건부 연산자를 사용하는 경우 혼합을 피하는 것이 좋습니다. 작성하는 동안 논리를 이해하기가 훨씬 쉬우 며 독자는 자신의 스타일을 좋아할 것입니다.


2
예 내 의견이 훨씬 더 떠들썩한 파티에서 조절이 작성해야하는 방법
derHugo

@takatakatek 이것이 내 경우에 왜 실패했는지 더 분명하게 만듭니다. 나는 이것에 대한 논리가 명확하지만 && 및 ||를 사용하여 조건을 그룹화하는 이유는 아니라는 것에 동의합니다. 조건문을 사용하여 표현하는 것을 피해야합니까?
kosol

@kosol 예, && 및 || 이전 명령의 종료 상태를 테스트하고 단일 명령 (또는 명령 그룹)을 실행 (&&) 또는 생략 (||)으로 지정합니다. 매우 간단한 경우에 유용 할 수 있지만 완전히 표현 된 if ... then ... elif ... else ... fi블록을 대체 할 수는 없습니다 . Bash에는 보다 정교한 언어로 볼 수 있는 실제 부울 유형 이 없다는 것을 알지 못할 수도 있습니다. 명령의 종료 상태가 0 이면 Bash는 해당 명령을 true / success 로 처리합니다 . 종료 상태가 0이 아닌 경우 Bash는이를 false / failure 로 처리합니다 .
takatakatek

7

오류 발생시 가장 간단한 방법은 bash -e옵션 ( set -e또는 /bin/bash -eshebang)을 사용하는 것입니다. 그러나 이렇게하면 사용자 지정 오류 메시지를 쉽게 보낼 수 없습니다. 더 간단하게 만들 수있는 몇 가지 관용구가 있습니다.

die 라 펄

Perl은 stderr에 메시지를 인쇄하고 예외를 발생 시키는 매우 편리한 die명령 을 가지고 있으며 , 이는 일반적으로 스크립트를 종료시킵니다. 이것을 에뮬레이션 할 수 있습니다 :

die () {
  ret=$?
  print "%s\n" "$@" >&2
  exit "$ret"
}

false || die "Obvious error because its false on left"
true || die "This shouldn't print"

trap ERR

trap <command>명령은 신호가 수신되거나 스크립트를 종료 할 때 ( trap ... EXIT) 또는 명령이 오류 ( trap ... ERR)를 반환 할 때 명령을 실행하는 데 사용할 수 있습니다 . 그래서 같은 :

trap 'ret=$?; printf "%s\n" "$ERR_MSG" >&2; exit "$ret"' ERR

그때:

ERR_MSG="Obvious error because its false here"
false
ERR_MSG="This shouldn't print"
true

두 경우 모두 exit 1스크립트가 실패 했음을 나타 내기 위해 적어도을 사용하는 것이 좋습니다 . 평야 exit는 이전 명령의 종료 상태를 사용하는데,이 경우 일반적으로 성공 하는 echoor printf명령입니다. 내가 한 것처럼 실패한 명령의 종료 상태를 저장하면 좋을 것입니다.


6

스크립트를 시작하여 조금 실험 해 볼 수 있습니다.

#!/bin/bash -e

-e는 무언가가 false를 반환하는 순간 스크립트가 종료되도록합니다. 그런 다음 특정 실패를 피할 수 있습니다something || true

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.