여러 논리 연산자((A || B) && C) 및 "예기치 않은 토큰 근처의 구문 오류"

여러 논리 연산자((A || B) && C) 및 "예기치 않은 토큰 근처의 구문 오류"

저는 Bash 3을 사용하고 있으며 조건을 작성하려고 합니다. C/C++에서는 매우 간단합니다 ((A || B) && C). Bash에서는 그런 식으로 작동하지 않습니다(Git 작성자가 다른 작업으로 넘어가기 전에 이 코드를 제공했음이 틀림없다고 가정합니다).

이것은 작동하지 않습니다. 이는 <0 or 1>문자열 리터럴이 아니며 0 또는 1(일반적으로 grep -i)을 나타냅니다.

A=<0 or 1>
B=<0 or 1>
C=<0 or 1>
if [ [ "$A" -eq "0" ] || [ "$B" -ne "0" ] ] && [ "$C" -eqe "0" ]; then ... fi

결과는 다음과 같습니다

line 322: syntax error near unexpected token `[['

그런 다음 다음을 시도합니다.

A=<0 or 1>
B=<0 or 1>
C=<0 or 1>
if [ ([ "$A" -eq "0" ]) || ([ "$B" -ne "0" ]) ] && [ "$C" -eq "0" ]; then ... fi

결과 :

line 322: syntax error near unexpected token `[['

문제의 일부는 검색 결과가 복합 조건이 포함된 더 복잡한 예가 아닌 간단한 예라는 것입니다.

((A || B) && C)Bash에서 간단한 작업을 수행하는 방법은 무엇입니까 ?


이를 확장하고 여러 블록에서 동일한 명령을 반복할 준비가 되었습니다.

A=<0 or 1>
B=<0 or 1>
C=<0 or 1>

if [ "$A" -eq "0" ] && [ "$C" -eq "0" ]; then
    ...
elif [ "$B" -ne "0" ] && [ "$C" -eq "0" ]; then
    ... 
fi

답변1

Bash의 구문은 C에서 영감을 받은 부분이 있지만 C와 다릅니다. 단순히 C 코드를 작성하고 그것이 작동할 것이라고 기대할 수는 없습니다.

쉘의 핵심은 명령을 실행하는 것입니다. 여는 괄호 명령 [은 단일 테스트를 실행하는 명령입니다. test(마지막 닫는 괄호 없이) 로 쓸 수도 있습니다 . ||연산자는 &&다음을 결합한 쉘 연산자입니다.주문하다, 테스트가 아닙니다.

그래서 글을 쓸 때

[ [ "$A" -eq "0" ] || [ "$B" -ne "0" ] ] && [ "$C" -eq "0" ]

다음과 같이 구문 분석됩니다.

[ [ "$A" -eq "0" ] ||
[ "$B" -ne "0" ] ] &&
[ "$C" -eq "0" ]

이는 다음과 같습니다.

test [ "$A" -eq "0" ||
test "$B" -ne "0" ] &&
test "$C" -eq "0"

불균형한 괄호가 보이시나요? 예, 좋지 않습니다. 괄호를 사용한 시도에는 동일한 문제가 있습니다. 즉 거짓 괄호입니다.

명령을 그룹화하는 구문은 중괄호입니다. 중괄호를 구문 분석하는 방법에는 앞에 완전한 명령이 필요하므로 중괄호 안의 명령을 종료하려면 줄 바꿈이나 세미콜론을 사용해야 합니다.

if { [ "$A" -eq "0" ] || [ "$B" -ne "0" ]; } && [ "$C" -eq "0" ]; then …

대안은 이중 괄호를 사용하는 것입니다. 단일 대괄호와 달리 이중 대괄호는 특별한 쉘 구문입니다. 그들은 경계를 그어조건식. 이중 괄호 안에는 &&및 등의 대괄호와 연산자를 사용할 수 있습니다 ||. 이중 괄호는 셸 구문이므로 셸은 이러한 연산자가 괄호 안에 있으면 일반 셸 명령 구문의 일부가 아니라 조건식 구문의 일부라는 것을 알고 있습니다.

if [[ ($A -eq 0 || $B -ne 0) && $C -eq 0 ]]; then …

모든 테스트가 수치인 경우 정의하는 다른 방법이 있습니다.산술 표현. 산술 표현식은 C와 매우 유사한 구문을 사용하여 정수 계산을 수행합니다.

if (((A == 0 || B != 0) && C == 0)); then …

당신은 찾을 수 있습니다내 배쉬 스탠드 입문서효과가있다.

[일반 sh에서 사용할 수 있습니다. bash(ksh 및 zsh 포함)에만 해당됩니다 [[.((

1 여러 테스트를 부울 연산자와 결합하는 것도 가능하지만 사용하기 번거롭고 미묘한 문제가 있으므로 설명하지 않겠습니다.

답변2

사용 [[:

if [[ ( "$A" -eq "0" || "$B" -ne "0" ) && "$C" -eq "0" ]]; then ...

원하는 경우 [다음을 수행할 수 있습니다.

if [ \( "$A" -eq "0" -o "$B" -ne "0" \) -a "$C" -eq "0" ]; then ...

답변3

-o중첩된 || 대신 연산자를 사용하세요 . -a필요한 경우 다른 문에서 && 대체를 사용할 수도 있습니다.

   EXPRESSION1 -a EXPRESSION2
          both EXPRESSION1 and EXPRESSION2 are true

   EXPRESSION1 -o EXPRESSION2
          either EXPRESSION1 or EXPRESSION2 is true


if [  "$A" -eq "0" -o "$B" -ne "0"  ] && [ "$C" -eq "0" ]; then echo success;fi

관련 정보