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

时间:2013-09-02 08:28:51

标签: 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

我做错了什么?

10 个答案:

答案 0 :(得分:901)

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

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

或者

if test "$#" -ne 1; then
    echo "Illegal number of parameters"
fi

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

[[ $# -ne 1 ]]

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

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

[[ ($# -eq 1 || ($# -eq 2 && $2 == <glob pattern>)) && $1 =~ <regex pattern> ]]

对于纯算术表达式,对某些表达式使用(( ))可能仍然会更好,但[[ ]]仍然可以使用-eq-ne-lt等算术运算符来实现它们。将表达式作为单个字符串参数放置{1}},-le-gt-ge

A=1
[[ 'A + 1' -eq 2 ]] && echo true  ## Prints true.

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

参考文献:

答案 1 :(得分:61)

如果你正在处理数字,那么使用arithmetic expressions可能是个好主意。

if (( $# != 1 )); then
    echo "Illegal number of parameters"
fi

答案 2 :(得分:33)

On []:!=,=,== ... string 比较运算符和-eq,-gt ...是算术二进制运算符。< / p>

我会用:

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

或者:

if [ $# -eq 1 ]; then

答案 3 :(得分:29)

如果您只是因为缺少某个特定参数而感到沮丧,Parameter Substitution很棒:

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

答案 4 :(得分:12)

可以使用以下方法完成一个简单的衬里工作:

[ "$#" -ne 1 ] && ( usage && exit 1 ) || main

这分解为:

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

    • usage()可以只是简单的echo&#34; $ 0:params&#34;
    • main可以是一个长脚本

答案 5 :(得分:1)

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

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

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

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

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

myFunc "$@"

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

答案 6 :(得分:0)

如果您想要安全,我建议使用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

在此处查看更多详细信息,例如http://wiki.bash-hackers.org/howto/getopts_tutorial

答案 7 :(得分:0)

这里有一个简单的衬里,用于检查是否只给出了一个参数,否则退出脚本:

[ "$#" -ne 1 ] && echo "USAGE $0 <PARAMETER>" && exit

答案 8 :(得分:0)

这里有很多很好的信息,但是我想添加一个我认为有用的简单代码段。

它与上面的有什么区别?

  • 将用法打印到stderr,比打印到stdout更合适
  • 使用其他answer中提到的退出代码返回
  • 不将它做成一个衬里...
_usage(){
    _echoerr "Usage: $0 <args>"
}

_echoerr(){
    echo "$*" >&2
}

if [ "$#" -eq 0 ]; then # NOTE: May need to customize this conditional
    _usage
    exit 2
fi
main "$@"

答案 9 :(得分:-1)

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

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

我希望这会有所帮助。