Or & And 연산자를 사용하는 것이 혼란스럽습니다.

Or & And 연산자를 사용하는 것이 혼란스럽습니다.
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실행되지 않는다는 것입니다. 더 이상 처리할 것이 없습니다. 줄 끝입니다.

관련 정보