我正在尝试创建一个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我也很好奇你是如何让脚本工作的,这样即使用户在‘-b’参数和'app_name‘参数之前输入新的flag+branch_name也无关紧要。但这可能不是目前最重要的事情。
要知道我到底想要构建什么,这里有一个指向我当前脚本的链接,该脚本只接受两个强制参数,并且只获取主分支:My Super Cool Artisan Executable Script
附注:我已经尝试了很多使用getopts的例子,我在Stackoverflow和其他博客上都找到了getopts,但没有一个能帮助我完全做到这一点。所以我在这里向你们这些伟大的人寻求帮助。
你好,维利
发布于 2013-06-10 10:39:11
我通常编写自己的代码,以允许使用短选项和长选项:
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[@]}"发布于 2013-06-10 10:40:13
Unix实用程序通常在位置参数之前采用可选参数(“标志”),尽管大多数GNU实用程序,包括C库函数getopt的GNU实现,都将命令行参数打乱,以便可选参数优先出现。但是,内置在getopts中的bash不能混洗,这意味着如果您愿意,可以由您决定是否这样做。
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 > $#))发布于 2013-06-11 16:30:33
稍微简化一点的版本,使用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无论如何,我建议使用标准的参数传递方式。您可以使用-n代替new。
https://stackoverflow.com/questions/17016007
复制相似问题