shell脚本里getopts的诡异现象

背景:
两地机房要做切换,因为距离太远,所以选择了双向主从,平时在备节点做read_only,为了快速切换只读状态写了个shell脚本来实现,遇到了些诡异问题
 
问题:
 
需要分两组进行,但是执行会报错!
[root@mailx switch]# vi read_only_set.sh       
#!/bin/bash
. ~/.bash_profile


ip1=10.xx.xx.xx
ip2=10.xx.xx.xx
ip3=10.xx.xx.xx
ip4=10.xx.xx.xx
ip5=10.xx.xx.xx
ip6=10.xx.xx.xx
ip7=10.xx.xx.xx
ip8=10.xx.xx.xx
ip9=10.xx.xx.xx
ip10=10.xx.xx.xx
ip11=10.xx.xx.xx
ip12=10.xx.xx.xx
ip13=10.xx.xx.xx
ip14=10.xx.xx.xx
ip15=10.xx.xx.xx
ip16=10.xx.xx.xx
ip17=10.xx.xx.xx
ip18=10.xx.xx.xx
ip19=10.xx.xx.xx

list[0]="$ip1 $ip2 $ip3 $ip6 $ip7 $ip9 $ip11 $ip13 $ip15 $ip16 $ip18"
list[1]="$ip4 $ip5 $ip8 $ip10 $ip12 $ip14 $ip17 $ip19"



while getopts "a:b" opt; do
case $opt in

a)
echo -e "\n西安:"
for j in ${list[1]}
do

echo -e "\n$j"
mysql --login-path=repl_check -h $j -e "set global read_only=$OPTARG; SHOW VARIABLES LIKE 'read_only';"|awk 'NR==2 {print $0}'

done
;;


b)
echo -e "\n北京:"
for i in ${list[0]}
do

echo -e "\n$i"
mysql --login-path=repl_check -h $i -e "set global read_only=$OPTARG; SHOW VARIABLES LIKE 'read_only';"|awk 'NR==2 {print $0}'

done
;;

\?)
echo "error option!"
;;
esac
done

执行:

QQ截图20180828093343.png


QQ截图20180828093539.png


a组执行正常,b组执行报错。如果把a组内容换到b组也会报错
 
 
 
如果冗余一组就不会出错。
[root@mailx switch]# vi read_only_set.sh       
#!/bin/bash
. ~/.bash_profile


ip1=10.xx.xx.xx
ip2=10.xx.xx.xx
ip3=10.xx.xx.xx
ip4=10.xx.xx.xx
ip5=10.xx.xx.xx
ip6=10.xx.xx.xx
ip7=10.xx.xx.xx
ip8=10.xx.xx.xx
ip9=10.xx.xx.xx
ip10=10.xx.xx.xx
ip11=10.xx.xx.xx
ip12=10.xx.xx.xx
ip13=10.xx.xx.xx
ip14=10.xx.xx.xx
ip15=10.xx.xx.xx
ip16=10.xx.xx.xx
ip17=10.xx.xx.xx
ip18=10.xx.xx.xx
ip19=10.xx.xx.xx

list[0]="$ip1 $ip2 $ip3 $ip6 $ip7 $ip9 $ip11 $ip13 $ip15 $ip16 $ip18"
list[1]="$ip4 $ip5 $ip8 $ip10 $ip12 $ip14 $ip17 $ip19"



while getopts "a:b:c" opt; do
case $opt in

a)
echo -e "\n西安:"
for j in ${list[1]}
do

echo -e "\n$j"
mysql --login-path=repl_check -h $j -e "set global read_only=$OPTARG; SHOW VARIABLES LIKE 'read_only';"|awk 'NR==2 {print $0}'

done
;;


b)
echo -e "\n北京:"
for i in ${list[0]}
do

echo -e "\n$i"
mysql --login-path=repl_check -h $i -e "set global read_only=$OPTARG; SHOW VARIABLES LIKE 'read_only';"|awk 'NR==2 {print $0}'

done
;;

c)
echo "nonthing" ;;

\?)
echo "error option!"
;;
esac
done
执行:

QQ截图20180828093343.png


QQ截图20180828094252.png


QQ截图20180828094304.png


 
 
试过几次,如果去掉mysql部分,直接打印,不会报错。如果加上mysql部分,没有c组就会报错。
测试是挨着?)的部分会报错,感觉可能是语法上出了问题,就是没找到什么问题。
已邀请:

robertshu

赞同来自:

while getopts "a:b:" opt; do
带b选项时 才能取到值
 
bash用 -x或echo调试即可 比较简单
 

liyh

赞同来自:

shell 语法用法,还是应该系统的查找官方解释,临时找的文档照葫芦画瓢,容易出奇葩问题。

rawdb

赞同来自:

问题解决了吗? 什么原因造成的? 

要回复问题请先登录注册