繁体   English   中英

如何验证Shell脚本中的参数数量(强制和可选)?

[英]How to validate the number of arguments (mandatory and optional) in a shell script?

我在验证脚本参数时遇到麻烦。 我正在尝试为我的脚本实现5个必需参数和2个可选参数。 到目前为止,这是我尝试过的。

#!/bin/sh

if [ $# -lt 5 ] || [ $# -gt 7 ]
then
  echo "Please supply 5 or 6 or 7 parameters. Aborting."
  exit 1
fi

echo MP1 = "$1"
echo MP2 = "$2"
echo MP3 = "$3"
echo MP4 = "$4"
echo MP5 = "$5"

while getopts c:a: optionalargs
do
        case $optionalargs in
          c)copt=$OPTARG;;
          a)aopt=$OPTARG;;
          *)echo "Invalid arg";;
        esac
done

if [ ! -z "$copt" ]
then
    export CHAR_SET=$copt
fi

if [ ! -z "$aopt" ]
then
    export ADDITIONAL_FLAGS=$aopt
fi

shift $((OPTIND -1))

echo OP_C = "${CHAR_SET}"
echo OP_A = "${ADDITIONAL_FLAGS}"

问题是验证此脚本的参数总数,因为我总共可以有5或7个参数。 提供-a additional -c character将被视为9个参数。

./a.sh 1 2 3 4 5 -a additional -c character
Please supply 5 or 6 or 7 parameters. Aborting.

我打开,没有设计-只要我能有强制性和可选参数。

如何正确验证?

Shell将每个空格分隔的字符串解释为一个新参数。 是否允许不带参数的-a标志或-c参数? 假设这些内容需要跟在后面,那么您实际上需要允许5或7或9个参数。 Getopts与初始shell参数解析是分开的。

除此之外,脚本看起来不错。 为了进行质量检查,我建议您使用Shellcheck

首先:shell对可选参数和强制参数一无所知,不特别处理以“-”开头的参数。 它只包含一个“单词”列表,由您的脚本来确定它们的含义。 getopts命令可以帮助解析参数,但是它处理的语法相当有限:

  • 选项以单个破折号开头,并且是单个字母(可能在其后带有参数)。 对于不带参数的选项,您可以在单个破折号上堆叠多个选项(例如ls -la )。
  • 在所有选项之后,可以有许多位置参数(顾名思义,这些位置参数的含义是通过它们在列表中的位置来定义的,例如,第一,第二等)。

有一些语法扩展(主要是GNU公约)认为getopts 支持:

  • 将选项放在位置参数之后(例如ls filename -l )。 选项必须始终是第一位的。
  • 长选项(多字母和/或双破折号,例如ls --all )。
  • 使用--将选项与位置参数分开。

因此,如果要使用getopts -style可选参数,则需要将它们放在参数列表的第一位。 并且在解析它们时,您需要先解析并从参数列表中删除它们(带shift ), 然后再检查位置参数的数量,并使用$1等访问位置参数。 您当前的脚本遇到了麻烦,因为它首先尝试处理位置参数,并且该方法不适用于getopts (至少没有一些繁琐的处理)。

如果需要更通用的参数语法,则可以使用getopt (请注意名称中缺少“ s”)。 有些版本的getopt支持GNU约定,有些则不支持。 有些还有其他问题。 IMO这是一罐最好不要打开的蠕虫。

另一种可能性是放弃-选项语法,并给出脚本,最后两个可以省略7个位置参数。 这样做的问题是,您不能省略第六个,而要通过第七个(除非您愿意将第六个视为等同于省略)。 该代码看起来像这样:

if [ $# -lt 5 ] || [ $# -gt 7 ]
then
  echo "Please supply 5 or 6 or 7 parameters. Aborting."
  exit 1
fi

echo "MP1 = $1"
echo "MP2 = $2"
echo "MP3 = $3"
echo "MP4 = $4"
echo "MP5 = $5"

if [ -n "$6" ]; then
    # This will run if a sixth argument was specified AND it wasn't blank.
    export CHAR_SET=$6
    echo "OP_C = ${CHAR_SET}"
fi

if [ $# -ge 7 ]; then
    # This will run if a seventh argument was specified EVEN IF it was blank.
    # If you want to omit this for a blank arg, use the `-n` test instead.
    export ADDITIONAL_FLAGS=$7
    echo "OP_A = ${ADDITIONAL_FLAGS}"
fi

...然后使用例如运行脚本

./a.sh 1 2 3 4 5 character additional    # Both optional args supplied
./a.sh 1 2 3 4 5 character               # Only first optional arg supplied
./a.sh 1 2 3 4 5 "" additional           # Only second optional arg supplied

或者,如果您确实想要更多扩展的语法,并且不想冒险遇到getopt命令的变化,则可以花费大量时间和精力来编写自己的解析系统。 海事组织,这是远远超出其价值的工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM