답변:
많은 컴퓨터 언어에서 우선 순위가 같은 연산자는 왼쪽 연관 입니다. 즉, 그룹화 구조가 없으면 가장 왼쪽의 작업이 먼저 실행됩니다. 배쉬 도이 규칙에서 예외 는 아닙니다 .
배쉬에서, 때문에 중요 &&
하고 ||
우선 순위가 동일합니다.
따라서 귀하의 예에서 가장 왼쪽에있는 작업 ( ||
)이 먼저 수행됩니다.
true || echo aaa
true
분명히 사실 이기 때문에 , ||
작업자 단락 및 전체 설명은 echo aaa
예상대로 평가할 필요없이 사실로 간주됩니다 . 이제 가장 올바른 작업을 수행해야합니다.
(...) && echo bbb
첫 번째 작업이 true로 평가되었으므로 (즉, 종료 상태가 0 임) 마치 마치 실행중인 것처럼
true && echo bbb
따라서 &&
단락되지 않으므로 bbb
에코가 표시됩니다.
당신은 같은 행동을 얻을 것이다
false && echo aaa || echo bbb
주석을 기반으로 한 메모
[[...]]
((...))
-o
-a
test
[
&&
-a
||
-o
것으로 보인다 C에서 와 C 같은 언어가 &&
더 높은 우선 순위를 가지고보다 ||
당신처럼 행동하는 원래의 구조를 예상 이유 아마
true || (echo aaa && echo bbb).
그러나 Bash의 경우에는 두 연산자가 모두 동일한 우선 순위를 가지므로 Bash는 왼쪽 연관 규칙을 사용하여 식을 구문 분석합니다. 이것을 제기 한 Kevin의 의견에 감사드립니다.
또한 경우가있을 수 있습니다 3 식이 평가됩니다. 첫 번째 명령이 0이 아닌 종료 상태를 반환하면 ||
단락되지 않고 두 번째 명령을 계속 실행합니다. 두 번째 명령이 종료 상태 0으로 돌아 가면 &&
단락되지 않으며 세 번째 명령이 실행됩니다. 이 문제를 제기 한 Ignacio Vazquez-Abrams의 의견에 감사드립니다.
&&
우선 순위가 높 ||
으므로 OP의 예상되는 동작이 발생합니다. 이러한 언어에 익숙하지 않은 사용자는 bash에서 동일한 우선 순위를 가지고 있다는 것을 인식하지 못할 수 있으므로 bash에서 동일한 우선 순위를 가지고 있음을보다 명확하게 지적 할 가치가 있습니다.
여러 가지 사항을 조건에 따라 설정하려면 다음을 그룹화하십시오.
true || { echo aaa && echo bbb; }
그 동안 아무것도 인쇄하지 않습니다.
true && { echo aaa && echo bbb; }
두 문자열을 인쇄합니다.
이것이 일어나는 이유는 요셉이 만드는 것보다 훨씬 간단합니다. 강타와 함께 무엇을 기억 ||
하고 &&
. 이전 명령의 반환 상태에 관한 것입니다. 원시 명령을 보는 문자 그대로의 방법은 다음과 같습니다.
( true || echo aaa ) && echo bbb
첫 번째 명령 ( true || echo aaa
)은으로 종료됩니다 0
.
$ true || echo aaa; echo $?
0
$ true && echo aaa; echo $?
aaa
0
$ false && echo aaa; echo $?
1
$ false || echo aaa; echo $?
aaa
0
(true || echo aaa) && echo bbb
는 내가 만들고있는 것입니다.
;
맨 끝에 세미 열이 있습니다. 이것이 없으면 작동하지 않습니다!
echo bbb;
첫 번째 예) 후 세미콜론이 누락되어 문제가 발생했습니다 . 내가 그것을 잃어 버렸다는 것을 알았을 때,이 대답은 내가 찾던 것입니다. 내가 원하는 것을 달성하는 방법을 알아낼 수 있도록 도와주는 +1!
&&
및 ||
운영자는되어 있지 경우 - 당시 다른 인라인 교체 정확한. 조심스럽게 사용하더라도 그들은 거의 같은 일을 할 수 있습니다.
단일 테스트는 간단하고 모호하지 않습니다 ...
[[ A == A ]] && echo TRUE # TRUE
[[ A == B ]] && echo TRUE #
[[ A == A ]] || echo FALSE #
[[ A == B ]] || echo FALSE # FALSE
그러나 여러 테스트를 추가하려고하면 예기치 않은 결과가 발생할 수 있습니다 ...
[[ A == A ]] && echo TRUE || echo FALSE # TRUE (as expected)
[[ A == B ]] && echo TRUE || echo FALSE # FALSE (as expected)
[[ A == A ]] || echo FALSE && echo TRUE # TRUE (as expected)
[[ A == B ]] || echo FALSE && echo TRUE # FALSE TRUE (huh?)
FALSE 와 TRUE 가 모두 에코되는 이유는 무엇 입니까?
여기에서 일어나고있는 것은 우리가 그것을 실현하지 않아도된다는 것입니다 &&
및 ||
조건 테스트 대괄호 안에 다르게 행동 사업자 오버로드 [[ ]]
그들이 AND에서 할 수 및 OR (조건부 실행) 목록은 우리가 여기보다 더합니다.
bash 맨 페이지에서 (편집 됨) ...
기울기
리스트는 연산자;, &, && 또는 ││ 중 하나로 분리되고 선택적으로;, &, 또는로 종료되는 하나 이상의 파이프 라인 시퀀스입니다. 이 목록 연산자 중 &&와 ││의 우선 순위는 같고; 우선 순위가 같은 & &.
명령을 구분하기 위해 하나 이상의 줄 바꿈 시퀀스가 세미콜론 대신 목록에 나타날 수 있습니다.
제어 연산자 &에 의해 명령이 종료되면, 쉘은 서브 쉘의 백그라운드에서 명령을 실행합니다. 쉘은 명령이 완료되기를 기다리지 않고 리턴 상태는 0입니다. 명령은;로 구분됩니다. 순차적으로 실행됩니다. 쉘은 각 명령이 차례로 종료되기를 기다립니다. 리턴 상태는 마지막으로 실행 된 명령의 종료 상태입니다.
AND 및 OR 목록은 각각 && 및 ││ 제어 연산자로 구분 된 하나 이상의 파이프 라인 시퀀스입니다. AND 및 OR 목록은 왼쪽 연관성으로 실행됩니다.
AND리스트의 형식은 ...
command1 && command2
command2는 command1이 종료 상태 0을 리턴하는 경우에만 실행됩니다.OR 목록의 형식은 ...
command1 ││ command2
command2는 command1이 0이 아닌 종료 상태를 리턴하는 경우에만 실행됩니다.AND 및 OR리스트의 리턴 상태는리스트에서 마지막으로 실행 된 명령의 종료 상태입니다.
마지막 예로 돌아가서 ...
[[ A == B ]] || echo FALSE && echo TRUE
[[ A == B ]] is false
|| Does NOT mean OR! It means...
'execute next command if last command return code(rc) was false'
echo FALSE The 'echo' command rc is always true
(i.e. it successfully echoed the word "FALSE")
&& Execute next command if last command rc was true
echo TRUE Since the 'echo FALSE' rc was true, then echo "TRUE"
괜찮아. 그것이 맞다면, 왜 마지막 예제 다음에 어떤 내용이 에코됩니까?
[[ A == A ]] || echo FALSE && echo TRUE
[[ A == A ]] is true
|| execute next command if last command rc was false.
echo FALSE Since last rc was true, shouldn't it have stopped before this?
Nope. Instead, it skips the 'echo FALSE', does not even try to
execute it, and continues looking for a `&&` clause.
&& ... which it finds here
echo TRUE ... so, since `[[ A == A ]]` is true, then it echos "TRUE"
둘 이상 &&
또는 ||
명령 목록에서 사용할 때 논리 오류의 위험 이 매우 높습니다.
추천
단일 &&
또는 ||
명령 목록에 예상대로 작동하므로 매우 안전합니다. else 절이 필요하지 않은 상황이라면 다음과 같은 것이 더 명확 해 질 수 있습니다 (마지막 중괄호는 마지막 두 명령을 그룹화해야합니다) ...
[[ $1 == --help ]] && { echo "$HELP"; exit; }
마지막을 제외한 각 명령이 테스트 (즉 , 대괄호 ) 인 다중 &&
및 ||
연산자 [[ ]]
는 일반적으로 마지막 연산자를 제외한 모든 연산자가 예상대로 동작하는 것처럼 안전합니다. 마지막 연산자는 then
or else
절 처럼 작동 합니다.
나는 이것에 혼란스러워하지만 여기 Bash가 당신의 진술을 읽는 방식에 대해 어떻게 생각하는지가 있습니다 (왼쪽에서 오른쪽으로 기호를 읽음).
true
. 명령의 끝에 도달하면이를 평가해야합니다. 이 시점에서 인수가 있는지 모릅니다. 실행 버퍼에 명령을 저장하십시오.||
. 이전 명령이 완료되었으므로 평가하십시오. 실행중인 명령 (버퍼) : true
. 평가 결과 : 0 (즉, 성공). "마지막 평가"레지스터에 결과 0을 저장하십시오. 이제 기호 ||
자체를 고려하십시오 . 이는 마지막 평가 결과가 0이 아닌 결과에 따라 다릅니다. "마지막 평가"레지스터를 점검하고 0을 찾았습니다. 0이 0이 아니므로 다음 명령을 평가할 필요가 없습니다.echo
. 다음 명령을 평가할 필요가 없으므로이 기호를 무시할 수 있습니다.aaa
. 이것은 명령 echo
(3)에 대한 인수 이지만 echo
(3)을 평가할 필요가 없으므로 무시할 수 있습니다.&&
. 이것은 마지막 평가 결과가 0 인 것에 달려 있습니다. "마지막 평가"레지스터를 점검하고 0을 찾았습니다. 0이 0이므로 다음 명령을 평가해야합니다.echo
. 다음 명령을 평가해야했기 때문에 명령 끝에 도달하면이 명령을 평가해야합니다. 실행 버퍼에 명령을 저장하십시오.bbb
. 이것은 명령 echo
(6)에 대한 인수 입니다. echo
평가가 필요 했기 때문에 bbb
실행 버퍼에 추가하십시오 .echo bbb
. 평가 결과 : 0 (즉, 성공). "마지막 평가"레지스터에 결과 0을 저장하십시오.물론 마지막 단계 bbb
는 콘솔에 에코됩니다.
&&
and 및||
shell 연산자는cmd1 && cmd2 || cmd3
우선 순위가 같지만&&
in((...))
및[[...]]
우선 순위는||
(((a || b && c))
is((a || (b && c)))
)입니다. 동일은 간다-a
/-o
에서test
/[
와find
및&
/|
에expr
.