如何验证 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 = ""
echo MP2 = ""
echo MP3 = ""
echo MP4 = ""
echo MP5 = ""
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.
我对没有 -
的设计持开放态度,只要我能够同时拥有强制参数和可选参数。
如何正确验证?
每个 space 分隔的字符串都将被 shell 解释为一个新参数。是否允许使用 -a
标志或不带参数的 -c
参数?假设那些需要跟随它们的东西,你实际上需要允许 5 或 7 或 9 个参数。 Getopts 独立于初始 shell 参数解析。
除此之外,脚本看起来不错。对于质量检查,我建议 Shellcheck
首先:shell 对可选参数和强制参数一无所知,不会特别处理以“-”开头的参数,诸如此类。它只有一个 "words" 的列表,由您的脚本来弄清楚它们的含义。 getopts
命令可以帮助解析参数,但它处理的语法相当有限:
- 选项以单个破折号开头,并且是单个字母(可能后面有一个参数)。对于不带参数的选项,您可以在单个破折号上堆叠多个选项(例如
ls -la
)。
- 在所有选项之后,可以有许多位置参数(这些参数的含义——顾名思义——根据它们在列表中的位置定义,例如第一、第二等)。
getopts
不支持许多语法扩展(主要是 GNU 约定):
- 将选项放在位置参数之后(例如
ls filename -l
)。选项必须始终放在第一位。
- 长选项(多字母 and/or 双破折号,例如
ls --all
)。
- 使用
--
将选项与位置参数分开。
所以如果你想使用getopts
风格的可选参数,你需要把它们放在参数列表的第一位。并且在解析它们时,您需要解析并从参数列表中删除*它们(使用shift
)在之前检查位置参数的数量,并使用</code> 等访问位置参数。您当前的脚本 运行 遇到了麻烦,因为它首先尝试处理位置参数,而这不适用于 <code>getopts
(至少在没有一些繁重的 kluging 的情况下)。
如果您需要更通用的参数语法,您可以使用 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 = "
echo "MP2 = "
echo "MP3 = "
echo "MP4 = "
echo "MP5 = "
if [ -n "" ]; then
# This will run if a sixth argument was specified AND it wasn't blank.
export CHAR_SET=
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=
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
命令的变幻莫测,您可以花费大量时间和精力编写自己的解析系统。在我看来,这比它的价值要多得多。
我无法验证我的脚本参数。我正在尝试为我的脚本实现 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 = ""
echo MP2 = ""
echo MP3 = ""
echo MP4 = ""
echo MP5 = ""
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.
我对没有 -
的设计持开放态度,只要我能够同时拥有强制参数和可选参数。
如何正确验证?
每个 space 分隔的字符串都将被 shell 解释为一个新参数。是否允许使用 -a
标志或不带参数的 -c
参数?假设那些需要跟随它们的东西,你实际上需要允许 5 或 7 或 9 个参数。 Getopts 独立于初始 shell 参数解析。
除此之外,脚本看起来不错。对于质量检查,我建议 Shellcheck
首先:shell 对可选参数和强制参数一无所知,不会特别处理以“-”开头的参数,诸如此类。它只有一个 "words" 的列表,由您的脚本来弄清楚它们的含义。 getopts
命令可以帮助解析参数,但它处理的语法相当有限:
- 选项以单个破折号开头,并且是单个字母(可能后面有一个参数)。对于不带参数的选项,您可以在单个破折号上堆叠多个选项(例如
ls -la
)。 - 在所有选项之后,可以有许多位置参数(这些参数的含义——顾名思义——根据它们在列表中的位置定义,例如第一、第二等)。
getopts
不支持许多语法扩展(主要是 GNU 约定):
- 将选项放在位置参数之后(例如
ls filename -l
)。选项必须始终放在第一位。 - 长选项(多字母 and/or 双破折号,例如
ls --all
)。 - 使用
--
将选项与位置参数分开。
所以如果你想使用getopts
风格的可选参数,你需要把它们放在参数列表的第一位。并且在解析它们时,您需要解析并从参数列表中删除*它们(使用shift
)在之前检查位置参数的数量,并使用</code> 等访问位置参数。您当前的脚本 运行 遇到了麻烦,因为它首先尝试处理位置参数,而这不适用于 <code>getopts
(至少在没有一些繁重的 kluging 的情况下)。
如果您需要更通用的参数语法,您可以使用 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 = "
echo "MP2 = "
echo "MP3 = "
echo "MP4 = "
echo "MP5 = "
if [ -n "" ]; then
# This will run if a sixth argument was specified AND it wasn't blank.
export CHAR_SET=
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=
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
命令的变幻莫测,您可以花费大量时间和精力编写自己的解析系统。在我看来,这比它的价值要多得多。