Linux BASH getopts可选参数
我正在尝试创建一个shell脚本,它有两个必需参数(arg1、arg2),然后是一个可选的-b标志,再加上用户选择使用该标志时需要遵循的参数 让我解释一下: 这是一个安装脚本,它利用GIT从Github存储库获取应用程序。终端f.ex中的用户类型:Linux BASH getopts可选参数,linux,bash,shell,unix,getopts,Linux,Bash,Shell,Unix,Getopts,我正在尝试创建一个shell脚本,它有两个必需参数(arg1、arg2),然后是一个可选的-b标志,再加上用户选择使用该标志时需要遵循的参数 让我解释一下: 这是一个安装脚本,它利用GIT从Github存储库获取应用程序。终端f.ex中的用户类型: ./shellscript.sh new <app_name> # fetches master branch by default /shellscript.sh新建 注:我一直在尝试使用getopts的许多例子,我在Stackove
./shellscript.sh new <app_name> # fetches master branch by default
/shellscript.sh新建
注:我一直在尝试使用getopts的许多例子,我在Stackoverflow和其他博客上都找到了这些例子,但没有一个能帮助我完全实现它。因此,我在这里向你们所有伟大的人寻求帮助
非常感谢,一定要查看我的
问候,,
Villi我通常会写自己的,以允许短选项和长选项:
function Usage()
{
cat <<-ENDOFMESSAGE
$0 [OPTION] REQ1 REQ2
options:
-b -branch branch to use
-h --help display this message
ENDOFMESSAGE
exit 1
}
function Die()
{
echo "$*"
exit 1
}
function GetOpts() {
branch=""
argv=()
while [ $# -gt 0 ]
do
opt=$1
shift
case ${opt} in
-b|--branch)
if [ $# -eq 0 -o "${1:0:1}" = "-" ]; then
Die "The ${opt} option requires an argument."
fi
branch="$1"
shift
;;
-h|--help)
Usage;;
*)
if [ "${opt:0:1}" = "-" ]; then
Die "${opt}: unknown option."
fi
argv+=(${opt});;
esac
done
}
GetOpts $*
echo "branch ${branch}"
echo "argv ${argv[@]}"
函数用法()
{
catUnix实用程序通常采用可选参数(“标志”)在位置参数之前,尽管大多数GNU实用程序,包括C库函数的GNU实现getopt
,都会对命令行参数进行洗牌,以便将可选参数放在第一位。但是,bash内置getopts
不会进行洗牌,这意味着如果您愿意,可以由您自己进行洗牌
getopts
总是以参数开头,该参数的编号是变量OPTIND
的值(每次执行bash函数时,OPTIND都设置为1,并且它是一个全局变量。因此,需要注意相互调用的bash函数。)如果愿意,您可以自己设置OPTIND,下一次调用getopts
将从该索引开始。或者,您可以使用shift
将所有命令行参数移到另一个索引上
例如,你可以这样做:
# "shift" version: always shift consumed arguments
local verb="$1" branch=master app_name option
shift
case $verb in
new) app_name="$1"
shift
while getopts b: option; do
case $option in
b) branch=$OPTARG;;
*) # handle the error;;
esac
done
shift $((OPTIND - 1));;
*) # handle the error or other subcommands;;
esac
# At this point, there are still arguments if ((OPTIND > 0))
或:
稍微简化一点的版本,使用getopts
可以报告错误:
#!/usr/bin/bash
help() { echo -e "Usage\n\t$0: new <app_name> [-b <develop>]" >&2;}
die() { [ -n "$1" ] && echo -e "Error: $1\n" >&2; help; [ -z "$1" ]; exit;}
[ $# -lt 2 ] && die "Too few args"
[ $1 != "new" ] && die "Bad first arg ($1)"
app_name=$2
shift 2
unset develop
while getopts "b:" opt; do
case $opt in
\?) exit 1;;
b) develop="$OPTARG";;
esac
done
echo "app_name: $app_name, develop: $develop"
无论如何,我可能建议使用标准的参数传递方式。您可以使用-n
Hi@rici,而不是new
,您的解决方案看起来非常有希望。尽管我得到了这个错误:“local:只能在函数中使用”。你会怎么做呢?谢谢!把它放在函数中,或者不用担心本地声明,这是你的选择。我喜欢把程序分解成函数,但是YMMV。如果你删除了本地声明,记得初始化变量。+1!对我来说,${!OPTIND}
是新的!IMHOOPTIND=((OPTIND+1))
不正确。要么OPTIND=$((OPTIND+1))
要么((OPTIND=OPTIND+1))
或者干脆(++OPTIND))
就行。我喜欢你的方法。我会测试一下。谢谢!请插入你尝试过的代码。
# non-shift version: use OPTIND to index arguments
local verb="${!OPTIND}" branch=master app_name option
OPTIND=$((OPTIND + 1))
case $verb in
new) app_name="${!OPTIND}"
OPTIND=$((OPTIND + 1))
while getopts b: option; do
case $option in
b) branch=$OPTARG;;
*) # handle the error;;
esac
done;;
*) # handle the error or other subcommands;;
esac
# At this point, there are still arguments if ((OPTIND > $#))
#!/usr/bin/bash
help() { echo -e "Usage\n\t$0: new <app_name> [-b <develop>]" >&2;}
die() { [ -n "$1" ] && echo -e "Error: $1\n" >&2; help; [ -z "$1" ]; exit;}
[ $# -lt 2 ] && die "Too few args"
[ $1 != "new" ] && die "Bad first arg ($1)"
app_name=$2
shift 2
unset develop
while getopts "b:" opt; do
case $opt in
\?) exit 1;;
b) develop="$OPTARG";;
esac
done
echo "app_name: $app_name, develop: $develop"
$./test new App
app_name: App, develop:
$./test new App -b Dev
app_name: App, develop: Dev