오늘 아침 내 검색은 bash에서 두 개의 십진수를 비교하는 방법에 관한 것이었고 다음 답변을 얻었습니다.쉘 스크립트에서 부동 소수점 숫자와 비교하는 방법. 그러나 여기에는 포함되지 않습니다.이 답변은 여기에 있습니다:
$ [[ ((3.56 < 2.90)) ]]; echo $?
1
$ [[ ((3.56 < 4.90)) ]]; echo $?
0
이 답변이 반대표를 받았고 다소 비정상적으로 굴욕적인 것처럼 보인다는 점을 고려할 때, 이 산술 평가의 정확성을 신뢰할 수 있습니까?
답변1
bash
부동 소수점 숫자를 이해하지 못합니다. 매뉴얼 페이지, 섹션
인용bash
산술 평가:
평가는 고정 너비 정수 [...]로 수행됩니다.
그래서 ((3 < 4))
or 는 ((3 < 2))
실제로 올바른 산술 표현입니다. 다음을 입력할 수 있습니다:
$ echo "$((3 < 4)) -- $((3 < 2))"
산출:
1 -- 0
그러나 $ echo $((3.3 < 3.6))
구문 오류 메시지가 반환됩니다. 귀하의 예에서는 실제로 문자열을 비교하고 있습니다. 다음은 몇 가지 예입니다.
$ [[ ((3.56 < 04.90)) ]]; echo $?
산출:
1
답변2
[[...]]
<
문자열 비교에 사용됩니다 .
따라서 [[ 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()