내 코드:
#!/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
합산에서의 산술평가는 유효하다.a
1+1
[ a -eq 1+1 ]