检查 bash 脚本的参数是所有数字的字符串

Fah*_*tha 4 shell scripting bash wildcards

猛砸FAQ

如果您要验证一个简单的“数字字符串”,则可以使用 glob 来完成:

# Bash
if [[ $foo = *[!0-9]* ]]; then
    echo "'$foo' has a non-digit somewhere in it"
else
    echo "'$foo' is strictly numeric"
fi
Run Code Online (Sandbox Code Playgroud)

我想,“天哪,这看起来不错而且简单”。然后我将它完全粘贴到脚本中,除了我在第一个 echo 之后添加了“exit 1”并更改$foo$1,因此它看起来像

if [[ $1 = *[!0-9]* ]]; then
    echo "'$1' has a non-digit somewhere in it"
    exit 1
else
    echo "'$1' is strictly numeric"
fi
Run Code Online (Sandbox Code Playgroud)

然后我尝试运行它并得到

$ sh foo.sh bar
bar
foo.sh: 6: [[: not found
'bar' is strictly numeric
Run Code Online (Sandbox Code Playgroud)

我是 Bash 文盲,我很惭愧,所以我不知道这里有什么问题。我的印象是,在线 Bash 手册支持与正则表达式匹配的运算符是=~,但更改它没有任何区别。[[在这里似乎有问题的那个运算符看起来很标准,尽管我不知道[[ ]]and之间有什么区别[ ],据我所知,它们都对应于测试表达式。我正在使用 Debian 挤压与 bash

$ bash --version
GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)
Run Code Online (Sandbox Code Playgroud)

Debian 说 version 4.1-3

Gil*_*il' 9

sh如果这是一个 bash 脚本,你为什么要打电话?很明显,在您的系统上,sh不是 bash,而是 Bourne/POSIX 系列中的其他一些 shell。事实上,它是dash,一个较小的外壳,专为低内存消耗和速度而设计,几乎只支持POSIX结构和内置实用程序。

[[ … ]]是 Bourne 语法的 ksh 扩展,它被 bash 和 zsh 但没有被 POSIX 接受。在可移植脚本中,您需要[ … ]用于测试。标准结构不支持模式匹配;标准习语是使用case构造

case $1 in                        # branch to the first pattern that $1 matches
  *[!0-9]*)                       # pattern = anything containing a non-digit
    echo not a number             # do this if the first pattern triggered
    ;;                            # end of this case branch
  *)                              # pattern = anything (else)
    echo successor of $(($1-1))   # do this if the second pattern triggered
    ;;                            # end of this case branch
esac                              # end of the case construct
Run Code Online (Sandbox Code Playgroud)

这是一个测试其参数是否为全数字的函数:

is_all_digits () {
  case $1 in *[!0-9]*) false;; esac
}
Run Code Online (Sandbox Code Playgroud)

题外话:我最初在上面的代码片段中打错了字:我写了$(($0-1)). 这导致了奇怪的错误消息:

$ ash foo.sh 42
foo.sh: 4: arithmetic expression: expecting EOF: "foo.sh-1"
$ ash ./foo.sh 42
./foo.sh: 4: arithmetic expression: expecting primary: "./foo.sh-1"
$ ksh ./foo.sh 42
./foo.sh: line 3: foo.sh: invalid variable name
$ pdksh ./foo.sh 42
./foo.sh[4]: ./foo.sh-1: unexpected `.'
$ bash foo.sh 42         
foo.sh: line 3: foo.sh-1: syntax error: invalid arithmetic operator (error token is ".sh-1")
$ bash ./foo.sh 42
./foo.sh: line 3: ./foo.sh-1: syntax error: operand expected (error token is "./foo.sh-1")
$ zsh foo.sh 42
foo.sh:3: bad floating point constant
Run Code Online (Sandbox Code Playgroud)

$0是脚本的名称,因此要计算的算术表达式是foo.sh-1or ./foo.sh-1。您可以观察 shell 中错误消息的多样性。我有点惊讶地看到 ash 的消息和 bash 的消息没有./最清楚:其他 shell 都没有提到问题出在算术表达式中。Ash 和 pdksh 确实因为报告错误一行太远而获得停靠点。