Bash if 语句帮助变量如 dl=40.00; $dl < 500

Bash if 语句帮助变量如 dl=40.00; $dl < 500
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“。由于赋值没有输出,因此结果只是设置dl800.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

对于不支持浮点运算的bashPOSIX语法,您可以调用进行比较:shawk

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如果您的awkGNU 实现可以帮助它识别更多形式的数字(例如, infinity, 0x10... 0x1p4YMMV 与其他实现)。这--有助于旧版本的 busybox awk,否则会将负数视为选项。这是为了在诸如(忽略尾随文本)0+之类的情况下强制进行数字比较,而不是在这些情况下诉诸字符串比较。compare '8 apples' '<' '10 bananas'

相关内容