
오늘 아침 내 검색은 bash에서 두 개의 십진수를 어떻게 비교할 수 있는지에 관한 것이었고 다음과 같은 답변을 얻었습니다.쉘 스크립트에서 부동 소수점 숫자와 비교하는 방법. 그러나 이것은 포함되지 않습니다이 답변은 여기:
$ [[ ((3.56 < 2.90)) ]]; echo $?
1
$ [[ ((3.56 < 4.90)) ]]; echo $?
0
답변이 반대표를 받았고 일종의 특이한 배시즘처럼 보인다는 점을 고려하면 이 산술 평가가 정확성에 대해 신뢰할 수 있습니까?
답변1
bash
부동 소수점 숫자를 이해하지 못합니다. 매뉴얼 페이지, 섹션
인용bash
산술 평가:
평가는 고정 너비 정수 […]로 수행됩니다.
그래서 ((3 < 4))
또는 ((3 < 2))
실제로 올바른 산술 표현입니다. 다음을 입력할 수 있습니다.
$ echo "$((3 < 4)) -- $((3 < 2))"
산출:
1 -- 0
그러나 $ echo $((3.3 < 3.6))
구문 오류 메시지가 반환됩니다. 귀하의 예에서는 실제로 문자열을 비교하고 있습니다. 따라서 몇 가지 예는 다음과 같습니다.
$ [[ ((3.56 < 04.90)) ]]; echo $?
산출:
1
답변2
내부는 [[...]]
<
문자열 비교를 위한 것입니다.
So [[ 3.56 < 2.90 ]]
or [[ (3.56 < 2.90) ]]
or [[ ((3.56 < 2.90)) ]]
or ...는 문자열과 문자열을 어휘적으로 [[ (((3.56 < 2.90))) ]]
비교하는 것입니다 (그리고 어휘적으로 는 예를 들어 보다 큽니다 ).3.56
2.90
3
10
[[ 3 -lt 2 ]]
정수 비교의 경우 또는 입니다 (( 3 < 2 ))
. 부동 소수점 비교를 원하면 , ksh93
또는 zsh
또는 와 yash
같은 외부 유틸리티가 필요합니다 . 할 수 없습니다.awk
perl
bash
예를 들어 다음과 같은 함수를 정의할 수 있습니다.
compare() (IFS=" "
exec awk "BEGIN{if (!($*)) exit(1)}"
)
예를 들어 다음과 같이 사용할 수 있습니다.
if compare '1.5*10 < 1e3'; then
echo less
fi
또는 그 문제에 있어서도:
if compare '"bar" < "foo"'...
문자열 비교를 수행합니다.
compare
명령 주입 취약점을 구성할 수 있으므로 제어되지 않은 외부 제공 데이터를 해당 함수에 전달하지 마십시오 (데이터는 awk
코드 로 해석되며 예를 awk
들어 명령을 실행할 수 있음 system()
).