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
。
但是,这一点很重要,管道在自己的子 shell 中运行,并且该子 shell 中设置的任何变量都不可用于父 shell。这意味着即使此分配实际上正在执行您希望它执行的操作,dl
仍然只能在该管道运行时进行设置,并且在脚本本身中取消设置。
然后,你运行这个:
if [ $((dl)) -lt 500 ]
这意味着“如果将变量的内容作为算术表达式命令执行的结果$dl
小于 500。为此,您需要将 的值设置dl
为有效的算术表达式。例如:
800/1
但是您拥有的是一个空变量,因为如上所述,该变量$dl
在运行管道的子 shell 中只有一个值。
无论如何,这一切确实是不必要的复杂。为什么不这样做:
#!/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
正如您所看到的,because$dl
是空的,但在算术表达式 ( ) 中使用$(( ))
,其计算结果为 0,并且您实际上正在运行[ 0 -lt 500 ]
,这始终为真。
答案2
只需使用像 zsh 这样具有浮点算术支持的 shell(您已经通过不引用您的 来编写 zsh 语法$((dl))
)而不是 bash 并执行以下操作:
downloadspeed=800.00
if ((downloadspeed < 500))
then
echo "slow - send slow message"
else
echo "fast - no issue"
fi
对于不支持浮点运算的bash
POSIX语法,您可以调用进行比较: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
如果您的awk
GNU 实现可以帮助它识别更多形式的数字(例如, infinity
, 0x10
... 0x1p4
YMMV 与其他实现)。这--
有助于旧版本的 busybox awk
,否则会将负数视为选项。这是为了在诸如(忽略尾随文本)0+
之类的情况下强制进行数字比较,而不是在这些情况下诉诸字符串比较。compare '8 apples' '<' '10 bananas'