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

我只想这样做:

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

有什么帮助吗?


当前回答

快速和肮脏:我知道这不是最优雅的方式,但我通常只是在上面加一个零并测试结果。像这样:

function isInteger {
  [ $(($1+0)) != 0 ] && echo "$1 is a number" || echo "$1 is not a number"
 }

x=1;      isInteger $x
x="1";    isInteger $x
x="joe";  isInteger $x
x=0x16 ;  isInteger $x
x=-32674; isInteger $x   

如果$1不是整数,$(($1+0))将返回0或炸弹。例如:

function zipIt  { # quick zip - unless the 1st parameter is a number
  ERROR="not a valid number. " 
  if [ $(($1+0)) != 0 ] ; then  # isInteger($1) 
      echo " backing up files changed in the last $1 days."
      OUT="zipIt-$1-day.tgz" 
      find . -mtime -$1 -type f -print0 | xargs -0 tar cvzf $OUT 
      return 1
  fi
    showError $ERROR
}

注意:我想我从来没有想过要检查会使整个脚本爆炸的浮点数或混合类型。。。在我的情况下,我不想再进一步了。我将使用mrucci的解决方案和Duffy的正则表达式-它们似乎是bash框架中最健壮的。。。

其他回答

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

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

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

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

…或,用符号处理数字:

^[+-]?[0-9]+([.][0-9]+)?$
[[ $1 =~ ^-?[0-9]+$ ]] && echo "number"

别忘了——包括负数!

我使用printf作为其他提到的答案,如果您提供格式字符串“%f”或“%I”,printf将为您进行检查。比重新发明支票更容易,语法简单简短,printf无处不在。所以在我看来,这是一个不错的选择——你也可以使用下面的想法来检查一系列的东西,它不仅对检查数字有用。

declare  -r CHECK_FLOAT="%f"  
declare  -r CHECK_INTEGER="%i"  

 ## <arg 1> Number - Number to check  
 ## <arg 2> String - Number type to check  
 ## <arg 3> String - Error message  
function check_number() { 
  local NUMBER="${1}" 
  local NUMBER_TYPE="${2}" 
  local ERROR_MESG="${3}"
  local -i PASS=1 
  local -i FAIL=0   
  case "${NUMBER_TYPE}" in 
    "${CHECK_FLOAT}") 
        if ((! $(printf "${CHECK_FLOAT}" "${NUMBER}" &>/dev/random;echo $?))); then 
           echo "${PASS}"
        else 
           echo "${ERROR_MESG}" 1>&2
           echo "${FAIL}"
        fi 
        ;;                 
    "${CHECK_INTEGER}") 
        if ((! $(printf "${CHECK_INTEGER}" "${NUMBER}" &>/dev/random;echo $?))); then 
           echo "${PASS}"
        else 
           echo "${ERROR_MESG}" 1>&2
           echo "${FAIL}"
        fi 
        ;;                 
                     *) 
        echo "Invalid number type format: ${NUMBER_TYPE} to check_number()." 1>&2
        echo "${FAIL}"
        ;;                 
   esac
} 

>$var=45

>$(($(check_number$var“${check_INTEGER}”“错误:找到$var-需要一个整数。”))&{echo“$var+5”|bc;}

这是一个有点粗糙的边缘,但有点新手友好。

if [ $number -ge 0 ]
then
echo "Continue with code block"
else
echo "We matched 0 or $number is not a number"
fi

这将导致一个错误,如果$number不是一个数字,则会打印“非法数字:”,但它不会跳出脚本。奇怪的是,我找不到一个测试选项来测试整数。这里的逻辑将匹配任何大于或等于0的数字。

Stack弹出了一条消息,问我是否真的想在回答30+后回答?但当然!!!使用bash新功能,如下所示:(在评论之后我做了更改)

函数isInt(){([[$1-eq$(($1+0))]]2>/dev/null&&[[$1!=“”]]&&echo 1)|| echo“”}

function isInt() {
   ([[ $1 =~ ^[-+0-9]+$  ]] && [[ $1 -eq $(( $1 + 0 )) ]] 2>/dev/null && [[ $1 != '' ]] && echo 1) || echo ''
}

支架:

===============out-of-the-box==================
 1. negative integers (true & arithmetic),
 2. positive integers (true & arithmetic),
 3. with quotation (true & arithmetic),
 4. without quotation (true & arithmetic),
 5. all of the above with mixed signs(!!!) (true & arithmetic),
 6. empty string (false & arithmetic),
 7. no value (false & arithmetic),
 8. alphanumeric (false & no arithmetic),
 9. mixed only signs (false & no arithmetic),
================problematic====================
 10. positive/negative floats with 1 decimal (true & NO arithmetic),
 11. positive/negative floats with 2 or more decimals (FALSE & NO arithmetic).

只有当与[[$(isInt<arg>)]]中的过程替换结合使用时,才能从函数中获得真/假,因为bash中没有逻辑类型,也没有函数的返回值。

当测试表达式的结果为“错误”时,我使用大写,反之亦然!

通过“算术”,我的意思是bash可以像以下表达式那样进行数学运算:$x=$(($y+34))。

当在数学表达式中,参数的行为与预期一致时,我使用“算术/无算术”;当参数与预期行为相比表现不佳时,我则使用“无算术”。

正如你所看到的,只有10和11是有问题的!

完美的

PS:请注意,最流行的答案在情况9中失败!