||와 함께 사용할 때 이 복합 명령 {...}이 오류와 함께 종료되지 않는 이유는 무엇입니까?

||와 함께 사용할 때 이 복합 명령 {...}이 오류와 함께 종료되지 않는 이유는 무엇입니까?

이 스크립트를 실행하려고 합니다.

#!/bin/bash -e

{ 
    echo "Doing something"; 
    will_fail                 # like `false` 

    echo "Worked"; 
} || echo "Failed"

놀랍게도 will_fail실패했지만 명령줄에 "실패"가 표시되지 않고 "작동"했습니다.

실패 후 복합 명령이 오류 없이 종료되는 이유는 무엇입니까 will_fail?

답변1

Failed복합 명령의 종료 상태는 에서 실행된 마지막 명령의 종료 상태이기 때문에 인쇄되지 않습니다 { ...; }. echoSuccess echo이므로 복합 명령은 종료 상태 0으로 종료됩니다.

다음은 세 개의 문자열을 출력합니다.

{ echo "Do something"; echo "Worked"; false; } || echo "Failed"

~에서POSIX 표준:

달리 명시하지 않는 한, 명령의 종료 상태는 해당 명령에 의해 실행된 마지막 단순 명령의 종료 상태입니다.


여기서는 여러 가지 일이 일어나고 있습니다(요약).

  • 당신은 set -e적극적으로 달리고 있습니다. 명령이 0이 아닌 종료 상태(대체로 말하면)를 반환하면 이로 인해 쉘이 종료됩니다. 그러나 명령이 ( 목록의 일부인 will_fail복합 명령)의 일부이기 때문에(그리고 목록의 마지막 명령이 아니기 때문에) 여기에는 적용되지 않습니다 .||

    또, 부터POSIX 표준(내 강조점):

    예약어 뒤에 ,,, 또는 복합 리스트를 실행할 때 -e, 예약어로 시작하는 파이프, 또는whileuntilifelif!어떤 명령이라도마지막 항목을 제외한 AND-OR 목록입니다.

  • 목록의 마지막 간단한 명령 ||은 입니다 echo "Failed". 이는 복합 명령의 전체 종료 상태를 결정합니다. 성공적으로 실행되었으므로(그리고 will_fail쉘이 종료되지 않았으므로) 상태는 0이 되며, 이는 반대쪽 끝이 ||실행되지 않음을 의미합니다.

답변2

제 생각에는소개하다허용된 답변( +1철저함을 위해 편집했음에도 불구하고)은 오해의 소지가 있으며, 존재하는 경우 정확한 문제를 설명하지 않습니다 set -e. 아래 줄의 나머지 부분에 답이 포함되어 있습니다. 제가 직접 여기까지 왔다가 애초에 잘못된 정보를 받았기 때문에 글을 쓰기로 결정했습니다.

복합 명령의 종료 상태는 { ...; 내에서 실행된 마지막 명령의 종료 상태이기 때문에 실패가 인쇄되지 않습니다. }, 이것이 에코입니다. echo가 성공하므로 복합 명령은 종료 상태 0으로 종료됩니다.

가장 먼저 전달해야 할 것은 여기 set -e에서위치{ ... }목록의 AND-OR입니다. 부품이 제거 되면 부품이 실패한 직후 || echo "Failed"복합 명령이 { ... }중단됩니다.최종주문도 안됐는데{ ... }

비교하다

#!/bin/bash -e

{ 
    echo "Doing something"; 
    false
    echo "Worked"; 
}

그 후에는 아무것도 인쇄하지 Doing something않고 오류와 함께 종료됩니다. 하지만 (이것이 대답이 잘못된 이유입니다) 내부의 마지막 복합 { ... }명령 입니다 echo.

하지만

#!/bin/bash -e

{ 
    echo "Doing something"; 
    false
    echo "Worked"; 
} || echo "Failed"

Worked인쇄 후에 Doing something는 호출이 이루어지지 않고 echo "Failed"종료 상태 0이 반환됩니다.

이유인용에 묻혀 있음(허용된 답변으로 더 자세히 제공됨): set -e장애가 있는AND-OR 명령의 일부인 모든 것.

후행의 경우 AND-OR 명령의 일부가 되므로 순종을 중단 || echo "Failed"합니다 . 중간은 흐름에 영향을 주지 않고 계속 진행되며 AND-OR에 0을 반환한 다음 호출 스크립트로 돌아갑니다.{...}set -efalseecho "Worked"

후행 명령이 없으면 그 자체 || echo "Failed"{ ... }일반적인 복합 명령 집합이며 POSIX에서 언급한 예외에 해당하지 않고 준수됩니다 set -e. 해당 부분에 도달하면 실행이 중지 false되고 실행 흐름이 해당 부분에 도달하지도 않아 echo "Worked"호출 스크립트에 오류가 반환됩니다.

관련 정보