1. 为了好玩和简化alias和function(将多个相关类似的合并成一个,通过选项和参数去选择功能),我开始修改自己的bash配置文件
2. 之前写了opts.sh作为测试getopts,还有getopt对应的opt.sh。一切运行良好!
3. 于是开始着手修改合并alias,结果奇葩的发现,只有第一次echo出了提示信息,后面的都出出现case里面的echo语句。
于是set -x,看到那些echo语句果然没有执行啊!!
4. 难道是mobaxterm的bash的问题,于是跑到服务器上去执行。结果一样啊!
5. 我能说只有在脚本里getopts才能正常吗?在bash shell下支持就有问题了?
但是我记得这个是内置命令了啊?getopt才是外置命令吧?!
6. 于是在服务器上仔细跑了一下。
结果发现每次重新登录,第一次运行都可以运行到case里面的echo语句。使用方向键,继续运行,就不行了。
于是继续在后面添加一样额选项和参数,看到新加的又继续执行echo了,老的就不会!
[root@mc-ssp@~@11:59:44]
2001 $ ngtossp -a -b 2 -c
the opt is a.
the opt is b. the value is 2
the opt is c.
the param is:
[root@mc-ssp@~@11:59:51]
2002 $ ngtossp -a -b 2 -c
the param is:
[root@mc-ssp@~@11:59:57]
2004 $ ngtossp -a -b 2 -c -b 2
the opt is b. the value is 2
the param is:
最后发现 但凡使用了ctrl-p或者上方向键 再次运行,case里面的echo就没有执行啊!!
getopts你也是吓到我不轻啊,感觉自己脑子都要歪掉了。
于是自己认为只能全部一个一个字母敲出来才能个多次运行。
结果事实还是不是这样的!!
真正的结果是,你可以使用向上方向键,但是你只能在原来基础上继续增加你的参数和选项,再次运行时只会使用追加的内容,前面相同的字数的内容是忽略的(即使内容不同也是)!
于是我非常怀疑是 shift $[ $OPTIND - 1] 导致的问题!
然而注释后也不行。最终不能解决!
同时发现函数里定义的变量会出现在运行过函数的shell中,只有加上local才能让变量变成函数内部有效。
最后找到上述问题的原因竟然也是 OPTIND 在运行后成为全局变量,导致后续使用出问题!
所以 在 shift $[ $OPTIND - 1] 后面加一行 : OPTIND=0
至此,问题完美解决! 函数可以用了! 脚本中不用加是因为他不会成为全局变量!
以下为从opts.sh提取放到bash配置文件中的函数形式,可供各位看管测试:
function opts(){
while getopts ab:c opt
do
case "$opt" in
a) echo "the opt is a.";;
b) echo "the opt is b. the value is $OPTARG " ;;
c) echo "the opt is c.";;
?) echo "Usage: `basename $0` [options] filename";;
*) echo "unknown args $opt";;
esac
done
shift $[ $OPTIND - 1]
OPTIND=0
echo "the param is:$@"
count=1
for par in "$@"
do
echo "the #$count param is $par"
count=$[ $count + 1]
done