提问人:triple fault 提问时间:9/2/2013 最后编辑:konsoleboxtriple fault 更新时间:3/24/2023 访问量:1125415
检查传递给 Bash 脚本的参数数
Check number of arguments passed to a Bash script
问:
我希望我的 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 ]; 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> ]]
对于纯算术表达式,使用 to some 可能仍然更好,但它们仍然可以与其算术运算符(如 、 、 、 、 )一起使用,或者将表达式作为单个字符串参数:(( ))
[[ ]]
-eq
-ne
-lt
-le
-gt
-ge
A=1
[[ 'A + 1' -eq 2 ]] && echo true ## Prints true.
如果您还需要将其与其他功能结合使用,这应该会有所帮助。[[ ]]
请注意,和 是与 、 、 和 具有相同解析级别的关键字。[[ ]]
(( ))
if
case
while
for
此外,正如 Dave 所建议的,错误消息最好发送到 stderr,这样当 stdout 被重定向时,它们就不会被包括在内:
echo "Illegal number of parameters" >&2
退出脚本
当向脚本传递无效参数时,使脚本退出也是合乎逻辑的。ekangas 的评论中已经建议了这一点,但有人编辑了这个答案以将其作为返回值,所以我不妨做对。-1
-1
虽然被 Bash 接受为参数,但没有明确记录,也不适合用作常见建议。 也是最正式的值,因为它是在 with 中定义的。大多数工具(如)也会返回无效参数。我也曾经在我的脚本中返回,但最近我不再真正关心,只是在所有错误中使用。但是,让我们放在这里,因为它是最常见的,可能不是特定于操作系统的。exit
64
sysexits.h
#define EX_USAGE 64 /* command line usage error */
ls
2
2
1
2
if [[ $# -ne 1 ]]; then
echo "Illegal number of parameters" >&2
exit 2
fi
引用
评论
[
which [
[
[[
[
[
command
exec
(>&2 echo 'Illegal number of parameters')
如果您正在处理数字,使用算术表达式可能是个好主意。
if (( $# != 1 )); then
>&2 echo "Illegal number of parameters"
fi
>&2
用于将错误消息写入 stderr。
评论
[ ... ]
$(( ))
(( ))
$
[ ]
[[ ]]
[ ]
(>&2 echo 'Illegal number of parameters')
在 []: !=, =, == ...是字符串比较运算符和 -eq, -gt ...是算术二进制的。
我会使用:
if [ "$#" != "1" ]; then
艺术
if [ $# -eq 1 ]; then
评论
==
实际上是一个未记录的功能,它恰好适用于 GNU 。它也恰好适用于 FreeBSD ,但可能不适用于 foo 。唯一的标准比较是(仅供参考)。test
test
test
=
dash
dash -c '[ 1 == 1 ]'
=
==
一个简单的 一个有效的衬里 可以使用:
[ "$#" -ne 1 ] && ( usage && exit 1 ) || main
这细分为:
- 测试 bash 变量的大小参数 $# 不等于 1(我们的子命令数)
- 如果为 true,则调用 usage() 函数并以状态 1 退出
- 否则调用 main() 函数
注意事项:
- usage() 可以只是简单的 echo “$0: params”
- main 可以是一个长脚本
评论
exit 1
( usage; false )
{ usage && exit 1; }
{ usage; exit 1; }
{...}
sh
如果你只对缺少特定参数的保释感兴趣,那么参数替换是很好的选择:
#!/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
在此处查看更多详细信息,例如 http://wiki.bash-hackers.org/howto/getopts_tutorial
评论
看看这个 bash 备忘单,它可以有很大帮助。
若要检查传入的参数的长度,请使用"$#"
若要使用传入的参数数组,请使用"$@"
检查长度和迭代的示例如下:
myFunc() {
if [[ "$#" -gt 0 ]]; then
for arg in "$@"; do
echo $arg
done
fi
}
myFunc "$@"
这篇文章帮助了我,但对我和我的情况来说缺少一些东西。希望这对某人有所帮助。
评论
这里有一个简单的行,用于检查是否只给出一个参数,否则退出脚本:
[ "$#" -ne 1 ] && echo "USAGE $0 <PARAMETER>" && exit
这里有很多很好的信息,但我想添加一个我认为有用的简单片段。
它与上面的一些有何不同?
- 将用法打印到 stderr,这比打印到 stdout 更合适
- 返回另一个答案中提到的退出代码
- 不会把它变成一个班轮......
_usage(){
_echoerr "Usage: $0 <args>"
}
_echoerr(){
echo "$*" >&2
}
if [ "$#" -eq 0 ]; then # NOTE: May need to customize this conditional
_usage
exit 2
fi
main "$@"
#!/bin/bash
Help() {
echo "$0 --opt1|-opt1 <opt1 value> --opt2|-opt2 <opt2 value>"
}
OPTIONS=($@)
TOTAL_OPTIONS=$#
INT=0
if [ $TOTAL_OPTIONS -gt 4 ]
then
echo "Invalid number of arguments"
Help
exit 1
fi
while [ $TOTAL_OPTIONS -gt $INT ]
do
case ${OPTIONS[$INT]} in
--opt1 | -opt1)
INT=`expr $INT + 1`
opt1_value=${OPTIONS[$INT]}
echo "OPT1 = $opt1_value"
;;
--opt2 | -opt2)
INT=`expr $INT + 1`
opt2_value=${OPTIONS[$INT]}
echo "OPT2 = $opt2_value"
;;
--help | -help | -h)
Help
exit 0
;;
*)
echo "Invalid Option - ${OPTIONS[$INT]}"
exit 1
;;
esac
INT=`expr $INT + 1`
done
这就是我的使用方式,它的工作没有任何问题
[root@localhost ~]# ./cla.sh -opt1 test --opt2 test2
OPT1 = test
OPT2 = test2
评论
test
test