이 스크립트를 실행하려고 합니다.
#!/bin/bash -e
{
echo "Doing something";
will_fail # like `false`
echo "Worked";
} || echo "Failed"
놀랍게도 will_fail
실패했지만 명령줄에 "실패"가 표시되지 않고 "작동"했습니다.
실패 후 복합 명령이 오류 없이 종료되는 이유는 무엇입니까 will_fail
?
답변1
Failed
복합 명령의 종료 상태는 에서 실행된 마지막 명령의 종료 상태이기 때문에 인쇄되지 않습니다 { ...; }
. echo
Success echo
이므로 복합 명령은 종료 상태 0으로 종료됩니다.
다음은 세 개의 문자열을 출력합니다.
{ echo "Do something"; echo "Worked"; false; } || echo "Failed"
~에서POSIX 표준:
달리 명시하지 않는 한, 명령의 종료 상태는 해당 명령에 의해 실행된 마지막 단순 명령의 종료 상태입니다.
여기서는 여러 가지 일이 일어나고 있습니다(요약).
당신은
set -e
적극적으로 달리고 있습니다. 명령이 0이 아닌 종료 상태(대체로 말하면)를 반환하면 이로 인해 쉘이 종료됩니다. 그러나 명령이 ( 목록의 일부인will_fail
복합 명령)의 일부이기 때문에(그리고 목록의 마지막 명령이 아니기 때문에) 여기에는 적용되지 않습니다 .||
또, 부터POSIX 표준(내 강조점):
예약어 뒤에 ,,, 또는 복합 리스트를 실행할 때
-e
, 예약어로 시작하는 파이프, 또는while
until
if
elif
!
어떤 명령이라도마지막 항목을 제외한 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 -e
false
echo "Worked"
후행 명령이 없으면 그 자체 || echo "Failed"
는 { ... }
일반적인 복합 명령 집합이며 POSIX에서 언급한 예외에 해당하지 않고 준수됩니다 set -e
. 해당 부분에 도달하면 실행이 중지 false
되고 실행 흐름이 해당 부분에 도달하지도 않아 echo "Worked"
호출 스크립트에 오류가 반환됩니다.