변수를 문자열 또는 정수로 비교할 때 중요한 차이점이 있습니까?

변수를 문자열 또는 정수로 비교할 때 중요한 차이점이 있습니까?

궁금해서 bash 변수 비교(값은 an )를 수행할 때 integeran 또는 a 로 선언된 int미리 정의된 값에 대해 테스트 할 수 있습니다 string.

샘플 스크립트:

#!/bin/bash
f1()
{
        [ "$1" == "1" ] && echo "$FUNCNAME: \"1\" compared as string"
}

f2()
{
        [[ "$1" -eq 1 ]] && echo "$FUNCNAME: \"1\" compared as int"
}

f1 $1
f2 $1

산출:

$  ./param.sh 1
f1: "1" compared as string
f2: "1" compared as int

그리고

$  ./param.sh blah
$

두 함수 모두 동일한 방식으로 동작하므로 정수 변수를 확인할 때 선호하는 방식이 있는지 궁금합니다. 더 엄격하기 때문에 intvs를 확인하고 싶지만 int이렇게 하면 단점이 있는지 궁금합니다 string.

이 경우 f2()비교도 더욱 엄격해집니다. 즉, 10진수 값을 전달하면 값이 깨지지만 f1()전달하면 문제가 없습니다.

답변1

예, 많은 차이점이 있습니다. 예를 들어, =문자열이 정확히 같은지 확인하고, -eq같은지 확인하기 전에 두 표현식에 대해 산술을 수행합니다.

$ [ " 1 " -eq 1 ] && echo equal || echo not
equal
$ [ " 1 " = 1 ] && echo equal || echo not
not

$ [ +1 -eq 1 ] && echo equal || echo not
equal
$ [ +1 = 1 ] && echo equal || echo not
not

$ [ "0+1" -eq 1 ] && echo equal || echo not
equal
$ [ "0+1" = 1 ] && echo equal || echo not
not

게다가 빈 문자열은 숫자상으로 정확히 0과 같습니다.

$ [ "" -eq 0 ] && echo equal || echo not
equal
$ [ "" = 0 ] && echo equal || echo not
not

비교 연산자를 도입하면 또 다른 종류의 차이점이 발생합니다. 예를 들어 <vs를 고려해보세요.-lt

$ [[ 2 -lt 10 ]] && echo less || echo not
less
$ [[ 2 < 10 ]] && echo less || echo not
not

이는 문자열 "2"가 문자열 "10" 뒤에 알파벳순으로 오지만(1이 2보다 먼저 오기 때문) 숫자 "2"가 숫자 "10"보다 수치적으로 작기 때문입니다.

답변2

정수 대 문자열 비교는 다음보다 크거나 작을 때 가장 중요합니다.

#!/bin/bash

eleven=11
nine=9

[[ $nine < $eleven ]] && echo string   # fail

[[ "$nine" -lt "$eleven" ]] && echo integer # pass

사전식으로 정렬할 때 9가 11 다음에 오기 때문에 첫 번째는 실패합니다.

따옴표를 사용한다고 해서 문자열을 비교할지 숫자를 비교할지 결정하는 것이 아니라 연산자가 결정합니다. 위의 따옴표를 추가하거나 제거할 수 있지만 아무런 차이가 없습니다. Bash는 이중 괄호 안에 정의되지 않은 변수를 캡처하므로 따옴표가 필요하지 않습니다. 수치 테스트를 위해 작은 괄호와 함께 따옴표를 사용하면 다음과 같은 이유로 비용이 절약되지 않습니다.

[ "" -lt 11 ]

어쨌든 오류입니다("정수 표현식이 필요합니다"). 따옴표는 단일 괄호 안의 문자열 비교에 대한 효과적인 보호 장치입니다.

[ "" \< 11 ]

댓글 내더블괄호 안은 ""will -eq 0이지만 will not 입니다 == 0.

답변3

말한 것 외에도.
쉘 스크립트에서는 빠른 계산이 거의 필요하지 않지만 숫자가 같은지 비교하는 것이 더 빠릅니다.

$ b=234
$ time for ((a=1;a<1000000;a++)); do [[ $b = "234" ]]; done

real    0m13.008s
user    0m12.677s
sys 0m0.312s

$ time for ((a=1;a<1000000;a++)); do [[ $b -eq 234 ]]; done

real    0m10.266s
user    0m9.657s
sys 0m0.572s

관련 정보