我的脚本需要两个参数才能运行。
如果需要的话,它可以有选项,所以我想确保这些属性,所以我写了以下脚本
if [ $# -lt 3 ]
then
echo "This command need 3 arguments"
else
echo $1 $2 $3
fi
观察到"$#"统计传递的参数总数,包括选项
OUTPUT :
sh my_script.sh -o optional1 -r.
它起作用,但由于我的检查失败,所以没有达到预期效果。
Expected Output :(two arguments are compulsory)
sh my_script.sh arg1 arg2 --> should work
sh my_script.sh -o optional1 -r optional2 --> throw error that it requires two arguments
sh my_script.sh -o optional1 -r optional2 arg1 arg2 --> should work
没有getopts,但基本相同,我更喜欢这种方式,因为添加长args更容易。
#!/bin/bash
while true;do
case $1 in
'-o'|'--optional')
optional1=$2
shift 2
;;
'-r')
optional2=$2
shift 2
;;
*)
break
;;
esac
done
if [[ $# -lt 2 ]];then
echo Too few args.
exit 1
fi
echo $optional1
echo $optional2
显然,它可能更健壮,因为这将使用多个相同的标志。
-
使用
getopts
处理选项。r_flag=0 o_flag="default value" while getopts o:r arg do case "$arg" in (o) o_flag="$OPTARG";; (r) r_flag=1;; (*) echo "Unrecognized option $arg" >&2; exit 1;; esac done
-
循环完成后,使用
shift $(($OPTIND - 1))
来消除已处理的选项。 -
现在您可以检查是否至少还有2个参数:
if [ $# -lt 2 ] then echo "Usage: $(basename $0 .sh) [-o option][-r] arg1 arg2 ..." >&2 exit 1 fi
注意,$#
报告参数数(positional parameters
)。它不在乎它们是什么。命令行上的任何内容都被视为参数。(例如somevar
或-o
)。因此,要区分-foo
和foo
,您需要编写一个解释器,或者使用其他人提供的getopts
(作为该解释器)
虽然getopts
很好,但我通常需要自己的翻译。为了在sh
中提供自定义解释器,您通常会使用while loop
、shift
和case
语句来检查每个位置参数并做出相应的响应。虽然与bash
相比,sh
中的字符串操作有些有限,但这已经足够了。
一个符合您要求的例子可能是:
#!/bin/sh
if [ $# -lt 2 ]; then
printf "This command need 2 argumentsn"
exit 1
fi
let nargs=0
while [ "$1" != "" ]; do
printf " processing: %sn" "$1"
case "$1" in
-r ) shift
[ "$1" = "" -o `expr index "$1" "-"` -eq 1 ] &&
{ printf "error: -r requires an option.n"; exit 1; }
r_var="$1"
printf " -r %sn" "$r_var"
let nargs=$nargs+1
;;
-* ) ;; ## don't count '-x' arguments as options (change as needed)
* ) let nargs=$nargs+1
;;
esac
shift
done
if [ $nargs -lt 2 ]; then
printf "n Two compulsory arguments not given.nn"
exit 1
else
printf "n required arguments satisfied.nn"
fi
exit 0
示例使用/输出
$ sh params.sh arg1 arg2
processing: arg1
processing: arg2
required arguments satisfied.
$ sh params.sh -o optional -r
processing: -o
processing: optional
processing: -r
error: -r requires an option.
$ sh params.sh -o optional -r arg1 arg2
processing: -o
processing: optional
processing: -r
-r arg1
processing: arg2
required arguments satisfied.
$ sh params.sh -o arg2
processing: -o
processing: arg2
Two compulsory arguments not given.
检查重复参数
如果您不想尝试覆盖case
语句中的所有内容,那么检查位置参数是否重复的嵌套for
循环可能是检查重复参数的最佳方式。一种方法是在脚本的开头进行检查:
#!/bin/sh
let args=2
## check duplicate arguments
for i ; do
for j in $(seq $args $#); do
printf "i: %s j: %s compare %s %sn" $i $j $i ${!j} ## delete - just for info
if [ $i = ${!j} ]; then
printf "error: duplicate args [ %s = %s ], exiting.n" $i ${!j}
exit 1;
fi
done
let args=$args+1
done
exit 0
示例/输出
$ sh pdupes.sh a b c d e
i: a j: 2 compare a b
i: a j: 3 compare a c
i: a j: 4 compare a d
i: a j: 5 compare a e
i: b j: 3 compare b c
i: b j: 4 compare b d
i: b j: 5 compare b e
i: c j: 4 compare c d
i: c j: 5 compare c e
i: d j: 5 compare d e
$ sh pdupes.sh a b c d b e
i: a j: 2 compare a b
i: a j: 3 compare a c
i: a j: 4 compare a d
i: a j: 5 compare a b
i: a j: 6 compare a e
i: b j: 3 compare b c
i: b j: 4 compare b d
i: b j: 5 compare b b
error: duplicate args [ b = b ], exiting.
防止两次接受争论
除了上面的循环检查将捕获任何重复项之外,您还可以向case
语句添加一个选项,以防止两次接受参数。这取决于你是想跳过重复还是标记它并退出。在带有可选参数的-o
的情况下,我会尝试下面的方法,它接受一个可选参数,测试它不是另一个-x
类型,并检查它是否已经设置。如果它通过了所有测试,就设置了`o_var,通过设置,它就不能再设置了:
-o ) shift
[ "$1" = "" -o `expr index "$1" "-"` -eq 1 -o ! -z $o_var ] &&
{ printf "duplicate value for '-o' received, exitingn"; exit 1; } ||
o_var="$1" && let nargs=$nargs+1
printf " -o %sn" "$o_var"
;;
轻微变化控制对重复的的响应
有两种额外的方式来处理多次尝试设置CCD_ 22。第一种是在参数列表中第二次出现-o
时退出(无论是否尝试设置与-o
相关的可选变量):
-o ) shift
## throw error on any second instance of '-o'
if [ -z "$o_var" ]; then
if [ ! `expr index "$1" "-"` -eq 1 -a "$1" != "" ]; then
o_var="$1"
let nargs=$nargs+1
printf " -o %sn" "$o_var"
fi
else
printf "error: multiple attempts to set '-o', exiting.n" "$o_var" "$1"
exit 1
fi
;;
示例
两次尝试再次设置-o
的处理方式相同:
$ sh params.sh -o foo -r arg1 arg2 -o bar
$ sh params.sh -o foo -r arg1 arg2 -o
processing: -o
-o foo
processing: -r
-r arg1
processing: arg2
processing: -o
error: multiple attempts to set '-o', exiting.
另一种可能性是,只有在第二次尝试设置与-o
相关联的可选变量时,才抛出错误。(例如,如果第二个-o
是无害的,则忽略它):
-o ) shift
## throw error only if second instance of '-o' has optional argument
if [ "$1" != "" -a ! `expr index "$1" "-"` -eq 1 ]; then
if [ -z "$o_var" ]; then
o_var="$1"
let nargs=$nargs+1
printf " -o %sn" "$o_var"
else
printf "error: multiple attempts to set '-o'. (%s, now '%s')n" "$o_var" "$1"
exit 1
fi
fi
;;
示例
$ sh params.sh -o foo -r arg1 arg2 -o bar
processing: -o
-o foo
processing: -r
-r arg1
processing: arg2
processing: -o
error: multiple attempts to set '-o'. (foo, now 'bar')
$ sh params.sh -o foo -r arg1 arg2 -o
processing: -o
-o foo
processing: -r
-r arg1
processing: arg2
processing: -o
required arguments satisfied.