我正在使用标准的getopts逻辑。但我想知道如何制作我提供的选项 - 互相排斥。 例如
shell.sh -a SID
<accepted>
shell.sh -b SID
<accepted>
shell.sh -ab SID
Message- using ab together is the same as running shell.sh without any options supplying just SID . Help usage < ya da ya >
shell.sh
Please enter SID at the minimum. Usage < ya da ya >
shell.sh SID
<accepted>
我正在尝试使用以下内容开发此逻辑
while getopts ":a:b:" opt; do
case $opt in
a ) SID="$OPTARG";;
set var=1
b ) SID="$OPTARG";;
set var=2
\?) echo "Invalid option: -"$OPTARG"" >&2
exit 1;;
) echo "Option -"$OPTARG" requires an argument." >&2
exit 1;;
esac
done
If (( val == 1 )) then ; # option a is invoked SID supplied
<stuff>
elif (( val == 2 )) then ; # option b is invoked SID supplied
<stuff>
else # SID supplied but neither a or b is invoked
<stuff>
fi
如何强制执行互斥标志。我确信有更多的acrobat方法可以做到这一点。我想我在这里错过了一些常识 - 并试图解决这个问题。 谢谢
$ more opt.ksh
die () {
echo "ERROR: $*. Aborting." >&2
return 1
}
var=
while getopts ":a:b:" opt; do
case $opt in
a ) SID="$OPTARG"
[ "$var" = 2 ] && die "Cannot specify option a after specifying option b"
[ "$OPTARG" = b ] && die "Do not specify b as a value for option a"
var=1
;;
b ) SID="$OPTARG"
[ "$var" = 1 ] && die "Cannot specify option b after specifying option a"
[ "$OPTARG" = a ] && die "Do not specify a as a value for option b"
var=2
;;
:) die "Must supply an argument to $OPTARG"
;;
\?) die "Invalid option: -$OPTARG. Abort"
;;
esac
done
shift $(($OPTIND - 1))
[ "$SID" ] || SID=$1
[ "$SID" ] || die "You must, at the minimum, supply SID"
我正在使用ksh
$ ps -p $$
PID TTY TIME CMD
1261 pts/45 00:00:00 ksh
我第一次运行它。
$ . opt.ksh -a 123 -b 123 # c0
ERROR: Cannot specify option b after specifying option a. Aborting.
-bash: /home/d1ecom1/gin1: No such file or directory
$ . opt.ksh -ab 123 # c1 should reject "cant use a and b togather. try with a or b"
-nologin: .[25]: shift: 4: bad number
$ . opt.ksh -a -b # c2 same as c1's message
$ . opt.ksh -a -b 123 # c3 same as c1
$ . opt.ksh -a -b 123 # c5
$ . opt.ksh -ab 123 # c6
$ . opt.ksh -a 123 -b 123 # c7
以上所有情况C0:C7都应该拒绝。注意C0和C7是相同的。然而,尽管这个C0给出了预期的错误,C7不会给出任何错误?
只有工作的人才应该
. opt.ksh -a 123
. opt.ksh -b 123
. opt.ksh 123
@hvd:TYSM回复。 我想添加一个additonal标志-p,它将提供一个“路径覆盖”选项。 所以也许我们必须扩展getopt以获取像这样的参数
die () {
echo "ERROR: $*. Aborting." >&2
exit 1
}
var=
opta=false
optb=false
while getopts ":ab:p" opt; do
case $opt in
a ) $optb && die "Cannot specify option a after specifying option b"
opta=true
;;
b ) $opta && die "Cannot specify option b after specifying option a"
optb=true
;;
p ) [ -d "$mypath" ] && die "path is invalid"
;;
\?) die "Invalid option: -$OPTARG. Abort"
;;
esac
done
shift $(($OPTIND - 1))
test $# -eq 0 && die "You must supply SID"
test $# -eq 1 || die "Too many command-line arguments"
# SID=$1
以上是旧方法。现在我有2个输入参数。一个是SID,另一个是路径。它是否像上面那样简单,或者我是否需要添加更多检查以防止其他不需要的组合。我想我试图瞄准的问题是,需要做出更多规定来允许这个-p参数,这是一个optiona覆盖参数。 - p可以与上面的任何参数共存但是我想一个要求是它应该紧跟在-p标志之后 所以这不应该允许 - 因为它不清楚。
shell.sh -b -p 123 /home/yadaya
再次感谢
答案 0 :(得分:2)
这使得选项a和b互斥:
die () {
echo "ERROR: $*. Aborting." >&2
exit 1
}
var=
while getopts ":a:b:" opt; do
case $opt in
a ) SID="$OPTARG"
[ "$var" = 2 ] && die "Cannot specify option a after specifying option b"
[ "$OPTARG" = b ] && die "Do not specify b as a value for option a"
var=1
;;
b ) SID="$OPTARG"
[ "$var" = 1 ] && die "Cannot specify option b after specifying option a"
[ "$OPTARG" = a ] && die "Do not specify a as a value for option b"
var=2
;;
:) die "Must supply an argument to $OPTARG"
;;
\?) die "Invalid option: -$OPTARG. Abort"
;;
esac
done
shift $(($OPTIND - 1))
[ "$SID" ] || SID=$1
[ "$SID" ] || die "You must, at the minimum, supply SID"
请注意,optargs将shell.sh -ab SID
解释为选项a
,其中参数b
后跟SID
作为脚本的参数,而不是选项的一部分。为了检测该问题,我们添加了涉及[ "$OPTARG" = b ] && die...
和[ "$OPTARG" = a ] && die...
的上述行。
您希望在未指定选项的情况下接受shell.sh SID
。这由case语句后的前两行处理。
答案 1 :(得分:1)
以下是如何在不将SID作为选项参数的情况下执行此操作,这对我来说更有意义:
die () {
echo "ERROR: $*. Aborting." >&2
exit 1
}
var=
opta=false
optb=false
while getopts ":ab" opt; do
case $opt in
a ) $optb && die "Cannot specify option a after specifying option b"
opta=true
;;
b ) $opta && die "Cannot specify option b after specifying option a"
optb=true
;;
\?) die "Invalid option: -$OPTARG. Abort"
;;
esac
done
shift $(($OPTIND - 1))
test $# -eq 0 && die "You must supply SID"
test $# -eq 1 || die "Too many command-line arguments"
SID=$1
我所做的改变是:
return 1
变为exit 1
(与您的问题无关,但die
听起来不应该继续)。 return 1
只会使die
函数返回非成功,但对die
的调用不会检查其结果,无论如何都会继续。getopts
字符串为:ab
而不是:a:b:
。无论你如何调用你的脚本,你总是需要传递一个SID,无论选项如何,所以将它作为选项的一部分包含在内是没有意义的。opta
和optb
变量中,以便于检查接受问题中的所有有效来电,拒绝所有无效的有效来电。但有一点值得关注:您的测试用例c7(-a 123 -b 123
)预计会失败,但确实会失败,但不会因为-a
和-b
合并而导致失败。相反,在我的方法中,由于-b
出现在非选项参数之后,它本身是一个非选项参数,拒绝它的原因变成“太多的命令行参数”。
答案 2 :(得分:0)
如果必须指定其中一个选项-s
,-i
或-h
,并且您还有两个选项{{1} }和-v
是可选的,您可以执行以下操作:
-n
摘自我的脚本,为了简化说明,省略了modes=0
while getopts :vs:i:h:n opt; do
case "$opt" in
v)
verbose='non-empty-string-true-flag'
;;
s)
((modes++))
: do something with OPTARG, the s form
;;
i)
((modes++))
: do something with OPTARG, the i form
;;
h)
((modes++))
: do something with OPTARG, the h form
;;
n)
dryrun='non-empty-string-true-flag'
;;
:)
printf 'Option -%s requires an argument\n' "$OPTARG" >&2
usage
exit 1
;;
*)
printf 'Invalid option: -%s\n' "$OPTARG" >&2
usage
exit 1
;;
esac
done
shift "$((OPTIND-1))"
if [ "$modes" -eq 0 ]; then
printf "Missing required option\n" >&2
usage
exit 1
elif [ "$modes" -gt 1 ]; then
printf "Error: -h, -i and -s are mutually exclusive and may only be used once\n" >&2
usage
exit 1
fi
,s
或i
个参数的处理。
脚本的概要如下:
h