如何在 bash 中获得 1 美元后的选择
How to getopts after $1 in bash
我想 运行 脚本作为 ./script speed -a some_value -b some_value
也 ./script accuracy -a some_value -b some_value
我试过的是
while [ -n "" ]; do
case "" in
speed)
for i in "${@:2}"
do while getopts "a:b:" opt; do
case "${opt}" in
a) list=$OPTARG
echo $list
;;
b) list2=$OPTARG
echo $list2
;;
esac
done
done
echo "speed option passed"
break ;;
accuracy) echo "similar to above function"
break ;;
*) echo "Option not recognized" ;; # In case you typed a different option other than a,b,c
esac
shift
done
获取与 运行 ./script speed -a some_value
时相同的输出
this is something
speed option passed
我不知道这是否可行,或者有什么办法可以做到这一点?
我认为您不需要外循环 (while [ -n "" ]; do
),除非您希望能够在单个 运行 中处理多个子命令。也就是说,你想要这样吗:
./script speed -a some_value -b some_value accuracy -a some_value -b some_value
大致相当于:
./script speed -a some_value -b some_value
./script accuracy -a some_value -b some_value
如果不是,请删除该循环,因为每个 运行 您将只处理一个子命令。如果您确实希望每个 运行 处理多个子命令,那么您需要采取一些额外的步骤来删除或跳过与一个子命令相关的参数,然后再 运行 执行下一个子命令。
您 想要删除 for i in "${@:2}"
循环——这与 getopts
的工作方式不相符。您需要做的是在处理选项之前跳过子命令名称。您可以使用 shift
删除子命令名称,如下所示:
case "" in
speed)
shift # Remove the first argument ("speed")
while getopts "a:b:" opt; do
...
如果您要允许多个子命令,请在 getopts
循环之后添加 shift $((OPTIND-1))
,以便为下一个子命令做好准备。
或者您可以修改 OPTIND
以告诉 getopts
它已经处理了第一个参数并且可以继续处理第二个参数:
case "" in
speed)
OPTIND=2 # Tell getopts to start processing at arg #2
while getopts "a:b:" opt; do
...
如果你要用这个方法处理多个子命令...好吧,它有点复杂,我想我会回避这个问题。
另一种选择是将每个子命令的代码放在一个函数中,并用除第一个参数以外的所有参数调用它:
speed_subcommand() {
local OPTIND
while getopts "a:b:" opt; do
...
}
case "" in
speed)
speed_subcommand "${@:2}" ;;
accuracy)
accuracy_subcommand "${@:2}" ;;
...
此方法并没有真正与每个 运行.
处理多个子命令混合使用
我想 运行 脚本作为 ./script speed -a some_value -b some_value
也 ./script accuracy -a some_value -b some_value
我试过的是
while [ -n "" ]; do
case "" in
speed)
for i in "${@:2}"
do while getopts "a:b:" opt; do
case "${opt}" in
a) list=$OPTARG
echo $list
;;
b) list2=$OPTARG
echo $list2
;;
esac
done
done
echo "speed option passed"
break ;;
accuracy) echo "similar to above function"
break ;;
*) echo "Option not recognized" ;; # In case you typed a different option other than a,b,c
esac
shift
done
获取与 运行 ./script speed -a some_value
this is something
speed option passed
我不知道这是否可行,或者有什么办法可以做到这一点?
我认为您不需要外循环 (while [ -n "" ]; do
),除非您希望能够在单个 运行 中处理多个子命令。也就是说,你想要这样吗:
./script speed -a some_value -b some_value accuracy -a some_value -b some_value
大致相当于:
./script speed -a some_value -b some_value
./script accuracy -a some_value -b some_value
如果不是,请删除该循环,因为每个 运行 您将只处理一个子命令。如果您确实希望每个 运行 处理多个子命令,那么您需要采取一些额外的步骤来删除或跳过与一个子命令相关的参数,然后再 运行 执行下一个子命令。
您 想要删除 for i in "${@:2}"
循环——这与 getopts
的工作方式不相符。您需要做的是在处理选项之前跳过子命令名称。您可以使用 shift
删除子命令名称,如下所示:
case "" in
speed)
shift # Remove the first argument ("speed")
while getopts "a:b:" opt; do
...
如果您要允许多个子命令,请在 getopts
循环之后添加 shift $((OPTIND-1))
,以便为下一个子命令做好准备。
或者您可以修改 OPTIND
以告诉 getopts
它已经处理了第一个参数并且可以继续处理第二个参数:
case "" in
speed)
OPTIND=2 # Tell getopts to start processing at arg #2
while getopts "a:b:" opt; do
...
如果你要用这个方法处理多个子命令...好吧,它有点复杂,我想我会回避这个问题。
另一种选择是将每个子命令的代码放在一个函数中,并用除第一个参数以外的所有参数调用它:
speed_subcommand() {
local OPTIND
while getopts "a:b:" opt; do
...
}
case "" in
speed)
speed_subcommand "${@:2}" ;;
accuracy)
accuracy_subcommand "${@:2}" ;;
...
此方法并没有真正与每个 运行.
处理多个子命令混合使用