检查传递给Bash脚本的参数数量

Naf*_*aly 663 bash parameter-passing command-line-arguments

如果不满足所需的参数计数,我希望我的Bash脚本能够打印错误消息.

我尝试了以下代码:

#!/bin/bash
echo Script name: $0
echo $# arguments 
if [$# -ne 1]; 
    then echo "illegal number of parameters"
fi
Run Code Online (Sandbox Code Playgroud)

由于某些未知原因,我遇到以下错误:

test: line 4: [2: command not found
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

kon*_*box 1000

就像任何其他简单命令一样,[ ... ]或者test在其参数之间需要空格.

if [ "$#" -ne 1 ]; then
    echo "Illegal number of parameters"
fi
Run Code Online (Sandbox Code Playgroud)

要么

if test "$#" -ne 1; then
    echo "Illegal number of parameters"
fi
Run Code Online (Sandbox Code Playgroud)

在Bash中,更喜欢使用,[[ ]]因为它不会对其变量进行单词拆分和路径名扩展,除非它是表达式的一部分,否则引用可能不是必需的.

[[ $# -ne 1 ]]
Run Code Online (Sandbox Code Playgroud)

它还有一些其他功能,如不带引号的条件分组,模式匹配(扩展模式匹配extglob)和正则表达式匹配.

以下示例检查参数是否有效.它允许一个或两个参数.

[[ ($# -eq 1 || ($# -eq 2 && $2 == <glob pattern>)) && $1 =~ <regex pattern> ]]
Run Code Online (Sandbox Code Playgroud)

对于纯算术表达式,使用(( ))一些仍可能会更好,但它们仍然可能在[[ ]]与它的算术运算符等-eq,-ne,-lt,-le,-gt,或-ge通过将表达为一个字符串参数:

A=1
[[ 'A + 1' -eq 2 ]] && echo true  ## Prints true.
Run Code Online (Sandbox Code Playgroud)

如果您需要将其与其他功能结合使用,这应该会有所帮助[[ ]].

参考文献:

  • @Leo命令可以是内置的,也可以不是。在bash中,`[`是内置函数,而`[[`是关键字。在一些较旧的shell中,甚至没有内置`[`。在大多数系统中,像[[]这样的命令自然可以作为外部命令共存,但是内部命令由Shell优先处理,除非您绕过`command`或`exec`。检查外壳的文档,了解它们如何评估。注意它们之间的差异,以及它们在每个外壳中的行为如何不同。 (4认同)
  • @timgeb 为了保持一致性。如果它不需要进行分词和文件名扩展,那么无论它的扩展值是否预计不受此类过程的影响,都应该将其引用。 (3认同)
  • OP:请记住,`[` 只是另一个命令,即尝试`which [`。 (2认同)
  • @Dave 我同意,但子外壳是不必要的。 (2认同)

Ale*_*-A. 67

如果你正在处理数字,那么使用算术表达式可能是个好主意.

if (( $# != 1 )); then
    echo "Illegal number of parameters"
fi
Run Code Online (Sandbox Code Playgroud)

  • @Max 算术扩展 ``$(( ))`` 并不花哨,应该由所有 POSIX shell 实现。但是,“(( ))”语法(不带“$”)不是其中的一部分。如果您由于某种原因受到限制,那么您当然可以使用“[ ]”代替,但请记住,您也不应该使用“[[ ]]”。我希望您了解 `[ ]` 的陷阱以及这些功能存在的原因。但这是一个 Bash 问题,所以我们给出 Bash 答案([“根据经验,[[ 用于字符串和文件。如果你想比较数字,请使用 ArithmeticExpression”](https://mywiki.wooledge .org/BashFAQ/031))。 (2认同)

jhv*_*ras 38

On []:!=,=,== ...是字符串比较运算符,-eq,-gt ...是算术二进制运算符.

我会用:

if [ "$#" != "1" ]; then
Run Code Online (Sandbox Code Playgroud)

要么:

if [ $# -eq 1 ]; then
Run Code Online (Sandbox Code Playgroud)

  • `==`实际上是一个未记录的特性,它**与GNU`test`一起使用.它也**与FreeBSD`test`一起使用,但*可能*不能用于*foo*`test`.*only*标准比较是`=`(只是FYI). (9认同)
  • 它记录在 bash man 条目中: *当使用 == 和 != 运算符时,运算符右侧的字符串被视为模式,并根据模式匹配下描述的规则进行匹配。如果启用了 shell 选项 nocasematch,则执行匹配时不考虑字母字符的大小写。如果字符串与模式匹配 (==) 或不匹配 (!=),则返回值为 0,否则返回值为 1。模式的任何部分都可以被引用以强制其作为字符串进行匹配。* (2认同)
  • @jhvaras:这正是Carpetsmoker所说的:它可以在某些实现中工作(实际上,它可以在Bash中工作),但是[不兼容POSIX](http://pubs.opengroup.org/onlinepubs/9699919799/utilities /test.html#tag_20_128)。例如,它将用dash _fail_:dash -c'[1 == 1]'`。POSIX仅指定“ =”,而不指定“ ==”。 (2认同)

Pat*_*Pat 33

如果您只对缺少某个特定参数的情况感兴趣,参数替换很棒:

#!/bin/bash
# usage-message.sh

: ${1?"Usage: $0 ARGUMENT"}
#  Script exits here if command-line parameter absent,
#+ with following error message.
#    usage-message.sh: 1: Usage: usage-message.sh ARGUMENT
Run Code Online (Sandbox Code Playgroud)

  • 当有人专门询问有关软件的问题(在本例中为 bash),然后人们抱怨回答问题的回复却使用了使生活更轻松但该软件独有的功能时,这只是网络幽默。再见,我要回到 Google 表格论坛抱怨他们的回复不适用于我的 Office 95 意大利语本地化版本。 (2认同)

Dwi*_*cer 13

可以使用以下方法完成简单的单线工作:

[ "$#" -ne 1 ] && ( usage && exit 1 ) || main
Run Code Online (Sandbox Code Playgroud)

这分解为:

  1. 测试参数大小的bash变量$#not equals 1(我们的子命令数)
  2. 如果为true,则调用usage()函数并退出状态1
  3. 否则调用main()函数

想一想:

  • 用法()可以简单回显"$ 0:params"
  • main可以是一个长脚本


jen*_*nki 7

查看 bash速查表,它可以提供很多帮助。

要检查传入的参数的长度,请使用 "$#"

要使用传入的参数数组,请使用 "$@"

检查长度并进行迭代的示例为:

myFunc() {
  if [[ "$#" -gt 0 ]]; then
    for arg in "$@"; do
      echo $arg
    done
  fi
}

myFunc "$@"
Run Code Online (Sandbox Code Playgroud)

这篇文章对我有所帮助,但对我和我的处境却缺少一些东西。希望这对某人有帮助。