-eq를 사용하여 문자열을 비교할 때 if 문은 [에서는 작동하지만 [[ 반복]에서는 작동하지 않습니다.

-eq를 사용하여 문자열을 비교할 때 if 문은 [에서는 작동하지만 [[ 반복]에서는 작동하지 않습니다.

내 코드:

#!/bin/bash

x=${#}

for (( a=0; a<x; ++a)); do
   if [[ $1 -eq $1 ]] 2> /dev/null
   then
      variable[a]=${1}
      shift
   else
      echo "The argument $1 is NOT an integer. Aborting this"
      exit 1
   fi
done
TOTAL=0
for (( a=0; a<x; ++a)); do
      echo "TOTAL : ${TOTAL}"
      TOTAL=$((TOTAL+variable[a]))
done
echo "Everything accounted to $TOTAL"
exit 0

따라서 기본적으로 스크립트의 인수를 가져와 요약합니다. 인수 중 하나가 정수가 아닌 경우 이를 알리고 스크립트를 종료해야 합니다.

이제 일어나는 일은 매개변수 중 하나가 정수가 아닌지 알려주지 않고 그냥 건너뛰는 것입니다. 따라서 매개변수 123 123 123 asdt를 지정하면 다음과 같은 결과를 얻습니다.

vagrant@localhost vagrant]$./super.sh 123 123 123 asdt
TOTAL : 0
TOTAL : 123
TOTAL : 246
TOTAL : 369
Everything accounted to 369
[07:43----------------------------------------
vagrant@localhost vagrant]$

하지만 이것을 이렇게 바꾸면:

for (( a=0; a<x; ++a)); do
   if [ $1 -eq $1 ] 2> /dev/null
   then

작동합니다. 다음을 얻습니다.

vagrant@localhost vagrant]$./super.sh 123 123 123 asdt
The argument asdt is NOT an integer. Aborting this
[07:44----------------------------------------
vagrant@localhost vagrant]$

왜 이런 일이 발생합니까?

답변1

이것이 Bash의 특별한 점 중 하나입니다 [[ .. ]]. [[ a -eq b ]]강제합은 산술식으로 처리 a되며 b, 그 안에서 문자열은 변수 이름으로 처리됩니다. 다른 표현식도 작동하므로 다음과 같이 할 수 있습니다.

$ a=2
$ [[ a -eq 1+1 ]] && echo yes
yes

반면에 은 [일반 명령이며 일반 명령과 동일한 구문을 따릅니다. 외부 바이너리로 구현될 수도 있습니다. 여기서는 그것을 [보고 a그것이 실제 정수가 아니라고 불평할 것입니다.

$ [ a -eq 2 ] && echo yes
bash: [: a: integer expression expected
$ /usr/bin/[ a -eq 2 ] && echo yes
/usr/bin/[: invalid integer ‘a’

그냥 다음과 같은 것을 사용하십시오

a=asdf
if [[ $a = *[^0-9]* ]]; then
    echo "'$a' isn't an integer"
fi

또는

a=asdf
case "$a" in 
    *[^0-9]*) echo "'$a' isn't an integer";;
esac

분명히 ksh합산에서의 산술평가는 유효하다.a1+1[ a -eq 1+1 ]

관련 정보