쉘 스크립트에서는 expr $a*$b
.$(($a+$b))
(($a+$b))
그러나 모든 리소스에서 (())
정수 계산에 사용 되므로 그냥 사용하지 않는 것이 좋습니다 .
그러면 $(())
변수가 있을 때 정수 값 대신 무엇을 사용해야 할까요? $(())
변수가 부동 소수점 값을 받을 수 있는 경우 대신 무엇을 사용해야 합니까?
답변1
산술의 경우
expr
이것은 고대입니다. 사용하지 마십시오. *$((...))
그리고((...))
매우 유사합니다. 둘 다 정수 계산만 수행합니다. 차이점은$((...))
계산 결과를 반환하는 것과((...))
계산 결과를 반환하지 않는 것입니다.$((...))
진술에 매우 유용합니다echo
.$ a=2; b=3; echo "$((a*b))" 6
((...))
변수를 할당하거나 종료 코드를 설정할 때 유용합니다.$ a=3; b=3; ((a==b)) && echo yes yes
부동 소수점 계산을 원하면
bc
또는 다음을 사용하십시오awk
.$ echo '4.7/3.14' | bc -l 1.49681528662420382165 $ awk 'BEGIN{print 4.7/3.14}' 1.49682
*BTW, expr
glob은 glob이 충분하지 않고 정규 표현식에 POSIX 메서드가 필요할 때 문자열 처리에 여전히 유용합니다.
답변2
expr은 오래되었지만 사용이 제한적이라고 생각합니다. 문자열을 검색한다고 가정해 보겠습니다. grep을 POSIX로 유지하려면 파이프를 사용해야 합니다.
if echo november | grep nov
then
: do something
fi
expr은 파이프 없이 이 작업을 수행할 수 있습니다.
if expr november : nov
then
: do something
fi
유일한 문제는 expr이 고정된 문자열에서 작동한다는 것입니다. 따라서 시작 부분 이후에 일치시키려면 REGEXP를 변경해야 합니다.
if expr november : '.*ber'
then
: do something
fi
(( ))
이 구조 에 대하여POSIX 아님, 그러니 피해야 합니다.
에 관해서는 $(( ))
달러 기호를 포함할 필요가 없습니다.
$ fo=1
$ go=2
$ echo "$((fo + go))"
3
답변3
다음 프로그램은 거의 동일한 작업을 수행하며 실제 차이점은 없는 것처럼 보입니다. 그러나 그것은 진실이 아니다.
#!/bin/bash
s=-1000
for (( i=0; i<1000000; i++ )); do
s=$((s+1))
done
echo "$s"
이것이 올바른 방법입니다. s+1 표현식은 쉘에 의해 평가되며 변수에 할당될 수 있습니다.
#!/bin/bash
s=-1000
for (( i=0; i<1000000; i++ )); do
s=`expr "$s" + 1`
done
echo "$s"
여기의 표현식은 내장 쉘이 아닌 외부 Unix 프로그램인 expr 프로그램에 의해 평가됩니다. 따라서 단순히 1을 더할 수는 없으며 sa 프로그램을 시작하고 해당 출력을 읽고 변수에 써야 합니다. 프로젝트를 시작하려면 많은 리소스와 시간이 필요합니다. 그리고 이 프로그램은 1,000,000번 실행되었습니다. 따라서 프로그램은 이전보다 훨씬 느려질 것입니다. 그래도 코드는 잘 작동합니다.
#!/bin/bash -e
s=-1000
for (( i=0; i<1000000; i++ )); do
((s=s+1))
done
echo "$s"
-e 플래그가 설정되지 않은 경우에도 프로그램은 정상적으로 작동합니다. 그러나 s=-1일 때 -e를 설정하면 ((s=s+1))이 계산됩니다. s=s+1 표현식은 0으로 평가되고 ((0))에는 종료 코드 >0이 있으며 이는 쉘에서 오류로 해석되어 쉘이 프로그램을 종료합니다.
-e 플래그를 설정하는 이유는 오류를 처리하는 가장 간단한 방법입니다. 오류가 발생하면 중지합니다.