쉘 비교에서 단일 및 이중 등호(=)의 차이점은 무엇입니까?

쉘 비교에서 단일 및 이중 등호(=)의 차이점은 무엇입니까?

내부의 문자열을 비교하려면 if이중 대괄호를 사용해야 한다는 점을 읽어보세요. 어떤 책에서는 비교가 로 이루어질 수 있다고 말합니다 =. 하지만 그것은 ==역시 작동합니다.

#!/bin/bash
a="hello"
b="world"
if [[ $a == $b ]];then
    echo "equal"
fi

비교에서 =와 사이에 차이가 있나요 ?==

답변1

bash( 해당 구문을 복사한 ksh위치 와 마찬가지로 bash) 비교 가 [[ $a == $b ]]아니라 패턴 일치입니다. [[ $a == "$b" ]]바이트 간 동등 비교가 필요합니다 . 를 지원하는 모든 쉘 =과 동일합니다 .==[[...]]

[[...]]표준 구문이 아닙니다 sh. 그만큼[ 명령표준이고, 표준이다비교연산자가 있습니다 =(일부 [구현에서는 ¹도 인식하지만 ==).

모든 명령에 대한 인수와 마찬가지로 변수 확장도 따옴표로 묶어야 합니다.분할+글로브빈 제거(후자만 수행됨 zsh)이므로 다음과 같습니다.

[ "$a" = "$b" ]

표준에서는 sh패턴 일치가 다음을 통해 수행됩니다 case.

case $a in
  ($b) ...
esac

완전성을 위해 다른평등한쉘 스크립트에서 볼 수 있는 연산자:

  • [ "$a" -eq "$b" ]: [십진수를 비교하는 표준 연산자입니다. 일부 [구현에서는 숫자 주위에 공백을 허용하고 일부에서는 임의의 산술 표현식을 허용하지만 이식성이 없습니다. 이식 가능한 경우 [ "$(($a))" -eq "$(($b))" ]이를 사용할 수 있습니다. [ "$((a == b))" -ne 0 ]다음과 같은 표준과 동등한 것이 무엇인지도 참조하십시오 (POSIXly를 제외하고 동작은 정수 상수를 포함 $a하는 경우에만 지정됩니다 $b).

  • ((a == b)), ksh에서, 및 에서도 발견되며 zsh, bash에 저장된 산술 표현식의 평가 결과가 의 $a결과와 동일한 경우 true를 반환합니다 $b. 일반적으로 숫자를 비교하는 데 사용됩니다. 산술 표현식이 평가되는 방법과 지원되는 숫자에 대해 쉘 간에 차이가 있습니다(예를 들어 bash 및 ksh의 일부 구현/버전은 부동 소수점을 지원하지 않거나 앞에 0이 있는 숫자를 8진수로 처리하지 않습니다).

  • expr "$a" = "$b"두 피연산자가 모두 10진 정수로 인식되면(일부는 숫자 주위에 공백을 허용함) 숫자 비교를 수행하고, 그렇지 않으면 두 문자열 피연산자의 정렬 순서가 동일한지 확인합니다. , ... 와 같은 연산자 인 $aor 값에 대해서도 실패합니다 .$bexpr(substr

  • awk -- 'BEGIN{exit !(ARGV[1] == ARGV[2])}' "$a" "$b": $a및가 $b숫자(적어도 10진수 정수 및 1.2, -1.5e-4와 같은 부동 소수점 숫자, 선행 후행 공백 무시, 일부는 16진수, 8진수 또는 로 인식되는 모든 항목 strtod())로 인식되면 숫자 비교가 수행됩니다. 그렇지 않으면 구현에 따라 바이트 간 문자열 비교이거나 비교와 마찬가지로 expr와 정렬 이 strcoll()같은지 여부입니다 .$a$b

또한보십시오:


¹ 여기에는 GNU [및 , , 일부 [기반 쉘이 포함되어 있지 않지만 일부는 기반 쉘이 포함되어 있지만 ,kshbashyashashzshzsh=cmd특수 파일 이름 확장 연산자입니다.(동일한 컨텍스트에서 확장됨 ~user) 해당 명령의 경로로 확장되므로 해당 기능을 비활성화하는 옵션을 끄지 않는 한 해당 equals기능을 작성해야 합니다. 그렇지 않으면 명령이 [ "$a" '==' "$b" ]오류가 발생합니다. =찾을 수 없습니다. 동일[ "$string" '=~' "$regexp" ]

답변2

이는 bash에서도 동일합니다:

[[ $x == "$y" ]]
[[ $x = "$y" ]]
[ "$x" == "$y" ]
[ "$x" = "$y" ]

처음 두 개의 $x 변수는 따옴표로 묶을 필요가 없습니다. Bash는 [ 내부에서 단어 분할 및 경로 이름 확장을 수행하지만 [[: 내부에서는 수행하지 않습니다.

$ x='a b'
$ [ -s $x ]
-bash: [: a: binary operator expected
$ [[ -s $x ]]
$ ls
$ [ a = * ]
-bash: [: a: unary operator expected
$ [[ a = * ]]
$ 

[[ $x = "$y" ]]문자열 비교이지만 [[ $x = $y ]]패턴 일치 표현식입니다.

$ y='a*'; [[ aa = "$y" ]]; echo $?
1
$ y='a*'; [[ aa = $y ]]; echo $?
0

-eq는 정수에만 사용해야 합니다.

$ [[ x.x -eq x.x ]]
-bash: [[: x.x: syntax error: invalid arithmetic operator (error token is ".x")
$ x=9; [[ "x" -eq 9 ]]; echo $?
0

또한보십시오BashFAQ/031: test, [ 및 [[ ?.

답변3

=및 둘 다 ==연산자입니다. C와 같은 일부 언어에서는 하나는 변수에 값을 할당하는 데 사용되고 다른 하나는 값(산술 표현식의 결과)을 비교하는 데 사용됩니다. 실제로 두 연산자 모두 산술 평가 내부의 연산자와 정확히 같습니다. A $((a=23))는 과제이고, a $((a==23))는 산술 비교입니다.

$ echo "$((a=11)) $((a==23))" "$((a=23))" "$((a==23))"
11 0 23 1

그러나 내부 테스트 구성(모두시험그리고[…]그리고[[...]]) 두 연산자 모두 동일한 의미를 가지며 동일한 작업을 수행합니다.

따라서 이 모든 옵션은 다음과 같습니다.

test "$a" =  "$b"
   [ "$a" =  "$b" ]
  [[ "$a" =  "$b" ]]
test "$a" == "$b"
   [ "$a" == "$b" ]
  [[ "$a" == "$b" ]]

~이다내부의 등가물세게 때리다이진 동등성을 테스트합니다(인용된 변수). 오른쪽 변수가 인용되지 않은 경우 패턴으로 해석되어 그에 따라 일치될 수 있습니다. 즉, 리터럴 문자열이 아닌 패턴으로 일치됩니다.

인용된 연산자 \=및 는 \==test 및 에서 사용될 때에도 동일합니다 […]. 그러나 인용된 연산자는 \==내부에서 실패합니다 [[…]].

다른 쉘의 경우 결과는 다양합니다(올바른 결과는 Y -true false이어야 하며 0(true) 및 1(false)과 다른 종료 코드는 실패로 보고됩니다 ¤). 일부 쉘은 실패합니다 - -(종료 코드는 항상 1입니다).

                     | dash  ksh   bash  zsh   
  test a  =  "$b"    | Y -   Y -   Y -   Y -    
     [ a  =  "$b" ]  | Y -   Y -   Y -   Y -    
    [[ a  =  "$b" ]] | ¤ ¤   Y -   Y -   Y -    
  test a  == "$b"    | ¤ ¤   Y -   Y -   - -    
     [ a  == "$b" ]  | ¤ ¤   Y -   Y -   - -    
    [[ a  == "$b" ]] | ¤ ¤   Y -   Y -   Y -    
  test a \=  "$b"    | Y -   Y -   Y -   Y -    
     [ a \=  "$b" ]  | Y -   Y -   Y -   Y -    
    [[ a \=  "$b" ]] | ¤ ¤   Y -   - -   - -    
  test a \== "$b"    | ¤ ¤   Y -   Y -   Y -    
     [ a \== "$b" ]  | ¤ ¤   Y -   Y -   Y -    
    [[ a \== "$b" ]] | ¤ ¤   Y -   - -   - -

모든 옵션은 ksh에서 작동하고, 인용된 연산자는 bash 및 zsh(내부 [[…]])에서 실패하고, 인용되지 않은 연산자 \=\==zsh(외부 [[…]])에서도 실패합니다.

관련 정보