downloadspeed=800.00
dl="$downloadspeed/1" | bc
if [ $((dl)) -lt 500 ]
then
echo "slow - send slow message"
else
echo "fast - no issue"
fi
내가 뭘 잘못했나요? $downloadspeed를 테스트하기 위해 다양한 변형을 시도했고 여기에 그대로 두었습니다. 어떻게 테스트하든 내 변수는 문자열로 처리되는 것 같습니다. $downloadspeed < 500, $dl < 500, "$dl" < 500 등과 같은 다양한 변형을 시도했습니다.
답변1
첫 번째 오류는 귀하의 과제입니다 dl
.
dl="$downloadspeed/1" | bc
이는 "변수를 $dl
다음으로 설정함을 의미합니다.끈 800.00/1
, 그런 다음 출력을 전달합니다.변수가 할당됨입니다 bc
. 할당에는 출력이 없으므로 결과는 dl
으로 설정됩니다 800.00
.
그러나 이것이 중요합니다. 파이프는 자체 하위 쉘에서 실행되며 해당 하위 쉘에 설정된 모든 변수는 상위 쉘에서 사용할 수 없습니다. 이는 이 할당이 실제로 원하는 작업을 수행하더라도 dl
해당 파이프라인이 실행되는 동안에만 설정하고 스크립트 자체에서 설정을 해제할 수 있음을 의미합니다.
그런 다음 다음을 실행합니다.
if [ $((dl)) -lt 500 ]
이는 "변수의 내용이 산술 표현식으로 실행되는 경우 명령 결과가 $dl
500 미만입니다. 이렇게 하려면 값을 dl
유효한 산술 표현식으로 설정해야 합니다. 예를 들면 다음과 같습니다.
800/1
$dl
그러나 위에서 언급한 것처럼 변수는 파이프를 실행하는 하위 셸에만 값을 갖기 때문에 빈 변수가 있습니다 .
어쨌든, 모든 것이 정말 불필요하게 복잡합니다. 이렇게 하면 안 되는 이유:
#!/bin/sh
downloadspeed=800.00
value=$(printf '%s\n' "$downloadspeed"/1 | bc)
if [ $value -lt 500 ]
then
echo "slow - send slow message"
else
echo "fast - no issue"
fi
다음에 이런 종류의 문제를 디버깅하려면 . set -x
:를 사용하여 스크립트 시작 부분에 추가할 수 있습니다.
#!/bin/sh
set -x
downloadspeed=800.00
dl="$downloadspeed/1" | bc
if [ $((dl)) -lt 500 ]
then
echo "slow - send slow message"
else
echo "fast - no issue"
fi
지금 스크립트를 실행하면 정확히 어떤 명령이 실행되고 있는지 확인할 수 있습니다.
$ foo.sh
+ downloadspeed=800.00
+ dl=800.00/1
+ bc
+ '[' 0 -lt 500 ']'
+ echo 'slow - send slow message'
slow - send slow message
보시다시피 $dl
는 비어 있지만 산술 표현식( )에 사용될 때 $(( ))
0으로 평가되고 실제로 실행 중이므로 [ 0 -lt 500 ]
이는 항상 true입니다.
답변2
$((dl))
bash 대신 부동 소수점 연산을 지원하는 zsh와 같은 셸(이미 zsh 구문을 인용하지 않고 작성함)을 사용 하고 다음을 수행하세요.
downloadspeed=800.00
if ((downloadspeed < 500))
then
echo "slow - send slow message"
else
echo "fast - no issue"
fi
부동 소수점 연산을 지원하지 않는 POSIX 구문의 경우 bash
비교를 호출할 수 있습니다.sh
awk
compare() { # args: <number> <op> <number>
POSIXLY_CORRECT=1 awk -- "
BEGIN {exit(!((0+ARGV[1]) $2 (0+ARGV[2])))}" "$1" "$3"
}
if compare "$downloadspeed" '<' 500
then
echo "slow - send slow message"
else
echo "fast - no issue"
fi
POSIXLY_CORRECT=1
GNU 구현이 더 많은 형태의 숫자를 인식하는 데 도움이 될 수 있는 경우 awk
(예: infinity
다른 구현의 YMMV 0x10
) 0x1p4
이는 음수를 옵션으로 처리하는 --
이전 버전의 busybox에 도움이 됩니다 . awk
이는 0+
(후행 텍스트 무시)와 같은 상황에서 문자열 비교를 사용하는 대신 숫자 비교를 강제하기 위한 것입니다.compare '8 apples' '<' '10 bananas'