gpt4 book ai didi

shell - 如何在你的 shell 中使用互斥标志并添加一个可选参数标志(使用 getopts)

转载 作者:行者123 更新时间:2023-12-04 00:44:07 25 4
gpt4 key购买 nike

我正在使用标准的 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

如何强制执行互斥标志。我确信有更多的杂技 Actor 方法可以做到这一点。我想我在这里遗漏了一些常识 - 并试图弄清楚这一点。谢谢

$ 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 为您的回复。我想添加一个附加标志 -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 参数,它是一个可选的覆盖参数。 -p 可以与上面的任何参数共存,但我想一个要求是它应该紧跟在 -p 标志之后所以这不应该允许 - 因为它不清楚。

shell.sh -b -p 123 /home/yadaya

再次感谢

最佳答案

在不将 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,因此将它作为选项的一部分包含在我看来是没有意义的。
  • 选项存储在 bool optaoptb 变量中以便于检查
  • 在传递所有选项后,将计算剩余的命令行参数。除非它正好是一个,否则对脚本的调用是无效的。

您在问题中的所有有效调用都被接受,所有无效调用都被拒绝。不过,对此感兴趣的一点是:您的测试用例 c7 (-a 123 -b 123) 预计会失败,并且确实会失败,但不是因为 -a-b 组合在一起。相反,在我的方法中,由于 -b 出现在非选项参数之后,它本身就是一个非选项参数,拒绝它的原因变成了“命令行参数太多”。

关于shell - 如何在你的 shell 中使用互斥标志并添加一个可选参数标志(使用 getopts),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21695565/

25 4 0