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

检查传递给Bash脚本的参数数,bash,parameter-passing,command-line-arguments,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 由于未知原因,我出现以下错误: test: line 4: [2: command not found 我做错了什么?就像任何其他简单命令一样,[…]或test的参数之间需要空格 i

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

我尝试了以下代码:

#!/bin/bash
echo Script name: $0
echo $# arguments 
if [$# -ne 1]; 
    then echo "illegal number of parameters"
fi
由于未知原因,我出现以下错误:

test: line 4: [2: command not found

我做错了什么?

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

if[“$#”-ne 1];然后
回显“参数数量非法”
fi

如果测试“$#”—ne 1;然后
回显“参数数量非法”
fi
建议 在Bash中,更喜欢使用
[[]]
,因为它不会对其变量进行分词和路径名扩展,除非引用是表达式的一部分,否则可能不需要引用

[$#-ne 1]]
它还具有一些其他特性,如不带引号的条件分组、模式匹配(扩展模式匹配与
extglob
)和正则表达式匹配

下面的示例检查参数是否有效。它允许一个或两个参数

[($#-eq 1 | |)($#-eq 2&&$2==)&&&$1=~]]
对于纯算术表达式,对某些表达式使用
(())
可能更好,但在
[[]]
中仍然可以使用其算术运算符,如
-eq
-ne
-lt
-le
-gt
,或
-ge
,将表达式作为单个字符串参数放置:

A=1
[['A+1'-eq 2]]&echo true##打印true。
如果您还需要将它与
[[]]
的其他功能结合使用,这将非常有用

请注意,
[[]]
(())
是与
if
case
while
for
具有相同解析级别的关键字

同样,正如所建议的,错误消息最好发送到stderr,这样在重定向stdout时就不会包含它们:

echo "Illegal number of parameters" >&2
退出脚本 当向脚本传递无效参数时,让脚本退出也是合乎逻辑的。这已经在by中提出了,但是有人编辑了这个答案,将它与
-1
作为返回值,所以我最好正确地执行它

-1
虽然被Bash作为
退出的参数接受,但没有明确的文档记录,不能作为普通建议使用
64
也是最正式的值,因为它是在
sysexits.h
中用
#define EX_USAGE 64/*命令行用法错误*/
定义的。像
ls
这样的大多数工具也会在无效参数上返回
2
。我也曾在脚本中返回
2
,但最近我不再真正在意,只在所有错误中使用
1
。但是让我们把
2
放在这里,因为它是最常见的,可能不是特定于操作系统的

if [[ $# -ne 1 ]]; then
    echo "Illegal number of parameters"
    exit 2
fi
工具书类

如果您正在处理数字,那么使用它可能是一个好主意

if($#!=1));然后
>&2回显“参数数量非法”
fi
&2
用于将错误消息写入stderr。

在[]上:!=,=,=。。。是字符串比较运算符和-eq,-gt。。。是算术二进制的

我将使用:

if [ "$#" != "1" ]; then
或:


使用以下方法可以实现简单的单衬套:

[ "$#" -ne 1 ] && ( usage && exit 1 ) || main
这可细分为:

  • 测试bash变量的参数大小$#不等于1(我们的子命令数量)
  • 如果为true,则调用usage()函数并以状态1退出
  • else调用main()函数
  • 注意事项:

    • 用法()只能是简单的回显“$0:params”
    • main可以是一个长脚本

    如果你只想在缺少某个特定论点的情况下保释,那么最好:

    #!/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
    

    应在测试条件之间添加空格:

    if [ $# -ne 1 ]; 
        then echo "illegal number of parameters"
    fi
    

    我希望这会有所帮助。

    如果你想安全起见,我建议使用getopts

    下面是一个小例子:

        while getopts "x:c" opt; do
          case $opt in
            c)
              echo "-$opt was triggered, deploy to ci account" >&2
              DEPLOY_CI_ACCT="true"
              ;;
                x)
                  echo "-$opt was triggered, Parameter: $OPTARG" >&2 
                  CMD_TO_EXEC=${OPTARG}
                  ;;
                \?)
                  echo "Invalid option: -$OPTARG" >&2 
                  Usage
                  exit 1
                  ;;
                :)
                  echo "Option -$OPTARG requires an argument." >&2 
                  Usage
                  exit 1
                  ;;
              esac
            done
    
    请参阅此处的更多详细信息,例如查看bash备忘单,它可以提供很多帮助

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

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

    检查长度和迭代的示例如下:

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

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

    这里有一个简单的单行程序来检查是否只给出了一个参数,否则退出脚本:

    [ "$#" -ne 1 ] && echo "USAGE $0 <PARAMETER>" && exit
    
    [“$#”-ne 1]&回显“用法$0”&退出
    
    这里有很多好的信息,但我想添加一个我觉得有用的简单片段

    它与上面的一些有什么不同

    • 将用法打印到stderr,这比打印到stdout更合适
    • 返回时,返回本节中提到的退出代码
    • 不会变成一行
    \u用法(){
    _Echorr“用法:$0”
    }
    _Echorr(){
    回显“$*”>&2
    }
    如果[“$#”-等式0];然后#注意:可能需要自定义此条件
    _用法
    出口2
    fi
    主“$@”
    
    您不应该为脚本命名
    test
    。这是标准Unix命令的名称,您不希望对其进行阴影处理。请在bash中的if语句中始终在“[”(“[”)或“(”(“)周围使用空格。若要添加到@zoska comment,您需要在“[因为它是作为命令实现的,请尝试使用”which“[”。下面的链接给出了更好的例子:@Barmar当然可以将它命名为
    test
    ,只要它不在路径上?
    ==
    实际上是一个未记录的特性,它恰好与GNU
    test
    一起工作。它也恰好与FreeBSD
    test
    一起工作,但可能不适用于foo
    test
    。唯一的标准是rd比较是
    =
    (仅供参考)。它记录在bash man条目中:当使用==和!=运算符时,运算符右侧的字符串被视为一种模式,并根据r匹配
    [ "$#" -ne 1 ] && echo "USAGE $0 <PARAMETER>" && exit