协慌网

登录 贡献 社区

如何在 Bash 中测试变量是否为数字?

我只是不知道如何确定传递给脚本的参数是否为数字。

我要做的就是这样:

test *isnumber* $1 && VAR=$1 || echo "need a number"

有什么帮助吗?

答案

一种方法是使用正则表达式,如下所示:

re='^[0-9]+$'
if ! [[ $yournumber =~ $re ]] ; then
   echo "error: Not a number" >&2; exit 1
fi

如果该值不一定是整数,请考虑适当修改正则表达式;例如:

^[0-9]+([.][0-9]+)?$

... 或使用带符号的数字来处理:

^[+-]?[0-9]+([.][0-9]+)?$

没有 bashisms(即使在 System V sh 中也可以工作),

case $string in
    ''|*[!0-9]*) echo bad ;;
    *) echo good ;;
esac

这将拒绝空字符串和包含非数字的字符串,并接受其他所有内容。

负数或浮点数需要做一些额外的工作。一个想法是排除- / .在第一个 “错误” 模式中添加更多包含错误使用方式的 “错误” 模式( ?*-* / *.*.*

以下解决方案也可以在诸如 Bourne 之类的基本 shell 中使用,而无需使用正则表达式。基本上,任何使用非数字的数值评估操作都将导致错误,该错误在 shell 中将被隐式视为 false:

"$var" -eq "$var"

如:

#!/bin/bash

var=a

if [ -n "$var" ] && [ "$var" -eq "$var" ] 2>/dev/null; then
  echo number
else
  echo not a number
fi

您还可以测试 $?该操作的返回码更为明确:

[ -n "$var" ] && [ "$var" -eq "$var" ] 2>/dev/null
if [ $? -ne 0 ]; then
   echo $var is not number
fi

标准错误的重定向是为了隐藏 “bash 打印出来的” 期望的整数表达式” 消息,以防万一我们没有数字。

注意事项(由于以下评论):

  • 带小数点的数字被标识为有效的 “数字”
  • 使用[[ ]]而不是[ ]总是评估为true
  • 大多数非 Bash Shell 总是将这个表达式评估为true
  • Bash 中的行为是未记录的,因此可能会更改,而不会发出警告
  • 如果值在数字后产生空格(例如 “1 a”),则产生错误,例如bash: [[: 1 a: syntax error in expression (error token is "a")
  • 如果该值与 var-name 相同(例如 i =“i”),则产生错误,例如bash: [[: i: expression recursion level exceeded (error token is "i")