我试图创建一个shell脚本,它有两个必需参数(arg1,arg2),然后是一个可选的-b标志加上用户选择使用该标志时需要遵循的参数。
让我解释一下:
它是一个安装脚本,它利用GIT从Github存储库中获取应用程序。用户键入终端f.ex。:
./shellscript.sh new <app_name> # fetches master branch by default
,脚本从此存储库中获取主分支的实例。然而,用户是否应该选择使用可选的-b标志,这意味着他/她想要指定要获取的分支,例如发展分支。意味着用户可以这样做:
./shellscript.sh new <app_name> -b develop # or which ever branch there is available
我也很好奇你如何才能使脚本正常工作,以便用户在新的&#39;之前键入-b标志+ branch_name并不重要。参数和&#39; app_name&#39;论点。但这可能不是目前最重要的事情。
要了解我正在尝试构建的内容,这里是指向我当前脚本的链接,该脚本仅接受两个必需参数并仅获取主分支:My Super Cool Artisan Executable Script
P.S。:我一直在尝试使用getopts的许多例子,我在Stackoverflow和其他博客上都找到了这些例子,但没有一个帮助我完全使用它。因此,我在这里向所有伟大的人寻求帮助。
此致 绒毛
答案 0 :(得分:5)
我通常会自己编写以允许短期和长期选择:
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[@]}"
答案 1 :(得分:2)
Unix实用程序通常在位置参数之前使用可选参数(“flags”),尽管大多数GNU实用程序,包括C库函数getopt
的GNU实现,随机命令行参数所以可选参数首先出现。但是,bash builtin 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))
或者:
# 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 > $#))
答案 2 :(得分:1)
稍微简化的版本,使用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"
测试:
$./test new App
app_name: App, develop:
$./test new App -b Dev
app_name: App, develop: Dev
无论如何,我可能会建议使用标准的参数传递方式。您可以使用new
代替-n
。