특정 명령에 대한 배쉬 무시 오류


444

다음 옵션을 사용하고 있습니다

set -o pipefail
set -e

bash 스크립트에서 오류 발생시 실행을 중지합니다. ~ 100 줄의 스크립트가 실행 중이고 스크립트의 모든 줄의 반환 코드를 확인하고 싶지 않습니다.

그러나 하나의 특정 명령에 대해서는 오류를 무시하고 싶습니다. 어떻게해야합니까?

답변:


757

해결책:

particular_script || true

예:

$ cat /tmp/1.sh
particular_script()
{
    false
}

set -e

echo one
particular_script || true
echo two
particular_script
echo three

$ bash /tmp/1.sh
one
two

three 인쇄되지 않습니다.

또한 pipefail켜져 있을 때 파이프의 명령 중 하나가 종료 코드가 아닌 종료 코드를 가질 때 셸이 전체 파이프에 0이 아닌 종료 코드가 있다고 생각하면 충분 pipefail합니다. .

$ set -o pipefail
$ false | true ; echo $?
1
$ set +o pipefail
$ false | true ; echo $?
0

15
+1. 배쉬 레퍼런스 매뉴얼로 설명 은 "쉘은 종료되지 않습니다" -e속성이 실패 명령이 즉시 다음 명령 목록의 일부인 경우 "로 설정 while하거나 until키워드를에서 시험의 일부 if진술은, 어떤 명령의 일부로 실행 A의 &&또는 ||최종 다음 명령을 제외 목록 &&이나 ||, 모든 명령 파이프 라인에 있지만 마지막, 또는 명령의 반환 상태가로 반전되고 있는지를 !. "
ruakh

@IgorChubin 왜 그런지 모르겠지만 이것이 작동하지 않습니다 출력 = (ldd $2/bin/* || true) | grep "not found" | wc -l스크립트가 ldd 반환 실패 시이 줄 다음에 종료됩니다
Vivek Goel

1
(ldd $2/bin/* || true) | grep "not found" | wc -l || true
Igor Chubin 2016 년

1
때문에 set -o pipefail. 때 grep발견 아무것도, 그것은 0이 아닌 종료 코드를 반환하고 쉘 전체 파이프가 0이 아닌 종료 코드를 가지고 있다고 생각하는 것이 충분하다.
Igor Chubin 2016 년

3
반환 값을 유지하는 옵션을 끝내려면 (종료하지 않고) my 명령 && true를 시도하십시오. 이를 통해 후속 단계에서 리턴 코드를 확인하고 프로그래밍 방식으로 처리 할 수 ​​있습니다.
Ed Ost

179

|| true오류를 무시하려는 명령 뒤에 추가하십시오 .


11
이 방법을 추가하는 것이 중요하다고 생각합니다.이 방법을 사용하면 응답 코드와 오류 메시지가 지속되지만 "!" 아래에 요약 된 방법은 응답 코드를 변경하여 오류를 생성하지 않습니다. set -e오류 메시지를 사용 하고 캡처 할 때 중요 합니다. 예 :set -e; TEST=$(foo 2>&1 || true); echo $TEST
Spanky

87

멈추지 말고 종료 상태를 저장하십시오.

특정 명령이 실패한 경우 스크립트를 중지하지 않고 실패한 명령의 오류 코드를 저장하려는 경우를 대비하여 :

set -e
EXIT_CODE=0
command || EXIT_CODE=$?
echo $EXIT_CODE

2
이것은 내가 필요 정확히
sarink

어떤 이유로 든 나를 위해 작동하지 않습니다 ... 아 잘
Jeef

EXIT_CODE는 명령이 0을 리턴 할 때 0으로 설정되지 않습니다. 0이 아닌 종료 코드는 캡처됩니다. 왜 그런지 알아?
Ankita13

@ Ankita13 그것이 0이라면 첫 번째 command는 성공적이었고 이후의 것을 실행할 필요가 있기 때문입니다 ||. 다음과 같이 읽으십시오 : command실패하면 EXIT_CODE=$?. command || echo "$?"더 자세한 디버깅을 위해 "트랩"을 사용하거나 사용할 수 있습니다 .
tinnick

63

더 간결하게 :

! particular_script

(강조 광산) 에 관한 POSIX 사양 에서 set -e:

이 옵션이 켜져 있으면 쉘 오류 결과에 나열된 이유로 간단한 명령이 실패하거나 종료 상태 값> 0을 리턴하고 while, until 또는 if 키워드 뒤에 오는 복합 목록의 일부가 아닌 경우 AND 또는 OR 목록의 일부가 아니며 !가 앞에 오는 파이프 라인이 아닙니다 . 예약어 이면 쉘이 즉시 종료됩니다.


16
이것은 명령의 종료 코드를 반전시키기 때문에 성공적으로 완료된 명령은 0 대신 1을 반환하고로 스크립트를 실패 -e합니다.
Marboni

17
내 이해는 !의지가 쉘이 무엇이든 나가지 못하게 한다는 것입니다. 이 스크립트스크립트를Still alive! 실행할 때 스크립트가 완료되었음을 나타내는 메시지를 표시합니다 . 다른 행동을보고 있습니까?
Lily Finley

7
당신이 맞습니다. 종료 상태를 반전 시키지만 명령이 0 또는 1로 끝날 때 스크립트가 충돌하지 않습니다. 어쨌든 문서를 인용 해 주셔서 감사합니다. 나는 표현을 if절에 넣고 문제를 해결했습니다.
Marboni

42

"true"를 반환하는 대신 "noop"또는 null 유틸리티 ( POSIX 사양 참조 )를 사용 :하고 "아무 것도하지 않음"을 사용할 수도 있습니다. 당신은 몇 글자를 저장합니다. :)

#!/usr/bin/env bash
set -e
man nonexistentghing || :
echo "It's ok.."

3
비록 || :는 ||만큼 명확하지 않습니다. 사실 (전문가가 아닌 사용자를 혼동시킬 수 있음), 간결함을 좋아합니다
David

이 변형은 CI에서 중요 할 수있는 텍스트를 반환하지 않습니다.
kivagant

5

당신이 당신의 스크립트 실패를 방지하려면 반환 코드를 수집

command () {
    return 1  # or 0 for success
}

set -e

command && returncode=$? || returncode=$?
echo $returncode

returncode 명령의 성공 여부에 관계없이 수집됩니다.


2

CLI 도구로 작업 할 때 아래 스 니펫을 사용하고 있으며 일부 리소스가 있는지 여부를 알고 싶지만 출력에 대해서는 신경 쓰지 않습니다.

if [ -z "$(cat no_exist 2>&1 >/dev/null)" ]; then
    echo "none exist actually exist!"
fi

1
이것은 정말 원형 교차로 및 적당히 비싼 방법으로 보인다if [ -r not_exist ]
tripleee

1

나는이 솔루션을 좋아한다.

: `particular_script`

백 틱 사이의 명령 / 스크립트가 실행되고 출력은 ":"명령 ( "true"와 동일)으로 공급됩니다.

$ false
$ echo $?
1
$ : `false`
$ echo $?
0

편집 : 못생긴 오타 수정



0

여기에서 해결책이 없었으므로 다른 해결책을 찾았습니다.

set +e
find "./csharp/Platform.$REPOSITORY_NAME/obj" -type f -iname "*.cs" -delete
find "./csharp/Platform.$REPOSITORY_NAME.Tests/obj" -type f -iname "*.cs" -delete
set -e

CI 및 CD에 유용합니다. 이렇게하면 오류 메시지가 인쇄되지만 전체 스크립트가 계속 실행됩니다.


0
output=$(*command* 2>&1) && exit_status=$? || exit_status=$?
echo $output
echo $exit_status

이것을 사용하여 로그 파일을 작성하는 예

log_event(){
timestamp=$(date '+%D %T') #mm/dd/yy HH:MM:SS
echo -e "($timestamp) $event" >> "$log_file"
}

output=$(*command* 2>&1) && exit_status=$? || exit_status=$?

if [ "$exit_status" = 0 ]
    then
        event="$output"
        log_event
    else
        event="ERROR $output"
        log_event
fi

0

위의 간단한 해결책에 감사드립니다.

<particular_script/command> || true

스크립트 단계 및 추가 흐름 제어 옵션의 추가 작업 / 문제 해결에 다음 구성을 사용할 수 있습니다.

if <particular_script/command>
then
   echo "<particular_script/command> is fine!"
else
   echo "<particular_script/command> failed!"
   #exit 1
fi

exit 1필요한 경우 추가 조치를 제동 할 수 있습니다 .

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