我从.bash_profile
调用以下脚本:
# Set directories based on current path
__set_dirs() {
currdir=`pwd`
if [[ ${currdir} =~ "\/path\/to\/main\/(.*)\/working\/([a-z]+)(/?.*)" ]]
then
ws=${BASH_REMATCH[1]}
subdirs=${BASH_REMATCH[3]}
stgdir=${ts}/${ws}/STAGING${subdirs}
else
echo "${currdir} is not a workspace"
stgdir=""
fi
}
# Update local version with staging version
upd() {
__set_dirs
if [[ -n ${stgdir} ]]
then
__overwrite=0
while getopts "o" opt
do
case $opt in
o)
__overwrite=1
;;
\?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done
echo "Updating ${currdir} with latest from ${stgdir}..."
if [ ${__overwrite} -eq 0 ]
then
update -r ${stgdir} ${currdir}
else
echo "Overwriting all local changes!"
update -r -w ${stgdir} ${currdir}
fi
fi
unset __overwrite
}
执行时
> upd -o
该标志被完全忽略 - 我从未看到“覆盖所有本地更改!”消息。我在某个地方错过了什么吗?
更新: 工作,但只有第一次时间我运行脚本。从第二次开始,该标志被忽略。
答案 0 :(得分:4)
好吧,想通了:
在搜索man page for getopts
之后,我发现了这个花絮(强调我的):
每次调用它时,getopts都会放置......下一个参数的索引 处理成变量OPTIND。 OPTIND初始化为1 调用shell或shell脚本的时间.... shell不会 自动重置OPTIND;它必须在两者之间手动重置 如果要使用一组新参数,则在同一个shell调用中多次调用getopts。
由于我只使用.bashrc运行一次脚本,OPTIND
只会初始化一次。我第一次运行这个功能,一切都是笨拙的。第二次打开时,OPTIND
设置为2,而getopts
找不到任何内容,因此会继续。
有了这些知识,我修改了upd()
以将OPTIND
重置为1:
upd() {
__set_dirs
if [[ -n ${stgdir} ]]
then
__overwrite=0
OPTIND=1
while getopts "o" opt
...
修复了它。 OPTIND
:比你想象的更重要。
答案 1 :(得分:2)
getopts
对传递给函数的参数起作用,因此在您的情况下,您必须使用upd()
调用"$@"
函数,以将所有命令行参数传递到函数中。
例如:
test() {
while getopts "o" opt; do
case $opt in
o)
echo o
;;
\?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done
}
test # this wont work as $1, $2, ... are not set
test $@ # this will work as you pass along the command line parameters
修改强>
我忽略了.bashrc
部分,如果我将上面的示例提供给我的运行shell,那么test -o
就会按预期工作。