echo 1 && false && echo 2 || echo 3
1
3
echo 2 || echo 3
2
위 코드에서 첫 번째 경우에는 왜 2가 인쇄되지 않습니까? 두 번째 경우에는 왜 2가 인쇄됩니까?
답변1
더 일반적인 질문쉘의 제어 및 리디렉션 연산자는 무엇입니까?그 대답은 아마도 귀하의 질문에 대한 답이 될 것입니다. 그러나 참고할 수 있도록 몇 가지 경험 법칙을 제시하겠습니다.
긴 목록 및/또는 목록이 있는 경우 각 목록을
||
"이 목록에서 가장 최근에 실행된 부분인 경우" 로 처리할 수 있습니다.실패, 다음 섹션을 실행하세요."(여기서 "실패"는 0이 아닌 종료 상태를 반환함을 의미함)동일한 유형의 추론을 사용하면
&&
"이 목록에서 가장 최근에 실행된 부분이성공적인, 다음 섹션을 실행하세요."(여기서 "성공"은 0 종료 상태 반환을 의미함)
위에서 설명한 내용은 일반적으로 알려진 내용입니다.단락 평가.
코드를 예로 들어 각 코드가 echo
실행될 기회가 있다고 가정합니다( echo
교체실패하다표준 출력 스트림이 닫힌 경우):
echo 1 && false && echo 2 || echo 3
첫 번째는 echo 1
성공하여 false
실행됩니다. false
(설계상) 실패하므로echo 2
확실히달리기. echo 3
, 반면에 false
가장 최근에 실행된 list() 부분이 실패했기 때문에 실행됩니다.
보고 있다
echo 2 || echo 3
여기서는 echo 2
먼저 실행되지만 echo 3
목록에서 가장 최근에 실행된 부분이 실패하지 않았기 때문이 아닙니다.
답변2
&&
||
이 답변에 대한 간단한 설명이 있습니다 .https://unix.stackexchange.com/a/31881/4506m그러나 구체적인 예에 대한 자세한 설명은 다음과 같습니다.
첫째, 유닉스 명령을 아는 것이 중요합니다성공또는실패하다그들이 어떤 결과물을 생산하거나 생산하지 않을 수 있는지에 관계없이. 보다 정확하게 말하면 명령은 종료 상태가 0이면 성공하고 종료 상태가 0이 아니면 실패합니다. 그러나 종료 상태 측면에서 생각하는 것은 혼란스럽습니다.
이를 고려하면 고려해 볼 수 있습니다.
cmd1 && cmd2 && ... && cmdN
명령은 실패할 때까지 왼쪽에서 오른쪽으로 평가됩니다.cmd1 || cmd2 || ... && cmdN
명령은 성공할 때까지 왼쪽에서 오른쪽으로 평가됩니다.
자, 시작해 봅시다당신의 첫 번째 예
echo 1 && false && echo 2 || echo 3
&&
괄호가 없으면 조합과 연산이 더욱 혼란스러워져 ||
의도한 그룹화가 불분명해집니다. &&
과 은 ||
우선순위가 동일하고 왼쪽으로 그룹화되어 있는 것으로 밝혀졌지만 이와 같이 혼합된 시퀀스는 종종 혼동을 줍니다. 이 표현의 정확한 의미는
( ( ( echo 1 && false ) && echo 2 ) || echo 3 )
좋아, 무슨 일이야?
쉘은 평가를 시작
( ... || echo 3 )
하지만 이를 수행하려면 먼저 왼쪽 명령을 평가해야 합니다.쉘은 평가를 시작
( ... && echo 2 )
하지만 이를 수행하려면 먼저 왼쪽 명령을 평가해야 합니다.쉘은 평가를 시작
( echo 1 && false )
하지만 이를 수행하려면 먼저 왼쪽 명령을 평가해야 합니다.쉘은
echo 1
항상 성공하는 것을 평가합니다. 즉, 상태 코드 0으로 종료됩니다.echo 1
연산자는 무언가가 인쇄된다는 사실에 신경 쓰지 않지만&&
출력의 첫 번째 줄인 을 해석합니다1\n
.첫 번째 피연산자의 왼쪽 피연산자가
( echo 1 && false )
성공하므로 쉘은 오른쪽 피연산자를 계속 평가합니다false
. 항상 실패하는 명령이므로&&
전체 표현식이 실패합니다.의 왼쪽 피연산자
( ... && echo 2 )
가 실패했으므로 쉘이확실히실행되고echo 2
표현식 자체가 실패합니다.왼쪽 피연산자가
( ... || echo 3 )
실패하므로 쉘은하다구현하다echo 3
. 이 명령은 두 번째 출력 라인을 생성하지만 더 중요한 것은||
연산자가 항상 성공하므로 및 연산자의 전체 시퀀스가echo
성공한다는 것입니다.&&
||
명령을 실행한 후 이를 입력하면
echo $?
값이 0으로 표시되어 이전 명령이 성공했음을 나타냅니다.
두 번째 예이는 위에서 설명한 것과 동일한 프로세스를 통해 평가할 수 있지만 더 자세히 살펴보겠습니다.
echo 2 || echo 3
이것은 첫 번째 예보다 훨씬 간단합니다. 쉘은 다음 단계를 수행합니다.
쉘은 계산을 시작
echo 2 || echo 3
하지만 이를 수행하려면 먼저 왼쪽을 계산해야 합니다.쉘 평가
echo 2
. 그러면 한 줄의 출력이 성공적으로 인쇄됩니다.쉘은 계속 평가
echo 2 || echo 3
하지만 이제 왼손이 성공하므로 상태 규칙은||
오른손을 전혀 평가하지 않습니다(따라서 다른 출력 행을 얻지 못합니다). 왼쪽이 성공하므로 전체||
표현식이 성공합니다.
꽤 자세하게 설명되어 있지만 도움이 되었으면 좋겠습니다.
답변3
쉘은 엄격한 왼쪽에서 오른쪽 순서로 명령을 실행합니다(OR 및 AND 목록의 경우).
이 명령에서:
echo 1 && false && echo 2 || echo 3
첫 번째 명령은 입니다 echo 1
. echo의 종료 상태는 항상 0이기 때문에 실행되고 종료 상태는 0
(처음에는 이미 0이었음에도 불구하고) 됩니다 0
.
첫 번째 명령이 발견되면 &&
종료 상태는 0(위에서)으로 실행이 성공한 후 &&
다음 명령이 수락되어 실행된다는 의미입니다.
실행되면 false
종료 상태는 1(실패)이 됩니다.
next 가 발견되면 &&
현재 종료 상태는 1, &&
거부되고 다음 명령( echo 2
)은 실행되지 않습니다.
하지만 해당 줄에는 아직 더 많은 코드가 있으므로 쉘은 다음 항목인 으로 이동합니다 . 이 시점의 현재 종료 상태 ||
로 다음 명령( )이 수락되고 실행됩니다.1
||
echo 3
이 명령은 echo 2 || echo 3
분석하기가 매우 쉽습니다. 첫 번째 명령은 (항상) 종료 코드를 얻기 위해 실행됩니다. 종료 코드는 0
다음 코드 ||
가 거부되어 echo 3
실행되지 않는다는 것입니다. 더 이상 처리할 것이 없습니다. 줄 끝입니다.