在shell脚本中,对于简单的参数,我们使用$1 $2
来处理即可,如下:
#!/bin/bash
SOFT_DIR=$1
MAVEN_DIR=$2
echo $SOFT_DIR
echo $MAVEN_DIR
-----------------
$ sh test.sh /home/soft /home/soft/maven
/home/soft
/home/soft/maven
但是,如果你的脚本参数非常多,那使用上面的这种方式就非常不合适,你无法清楚地记得每个位置对应的是什么参数。所以,我们可以使用bash内置的getopts
,下面是一个简单的例子:
#!/bin/bash
usage() {
echo "Usage:"
echo " test.sh [-j JAVA_DIR] [-m MAVEN_DIR]"
echo "Description:"
echo " JAVA_DIR, the path of java."
echo " MAVEN_DIR, the path of maven."
exit -1
}
upload="false"
while getopts 'h:j:m:u' OPT; do
case $OPT in
j) JAVA_DIR="$OPTARG";;
m) MAVEN_DIR="$OPTARG";;
u) upload="true";;
h) usage;;
?) usage;;
esac
done
echo $JAVA_DIR
echo $MAVEN_DIR
echo $upload
---------------------------
$ sh test.sh -j /home/soft/java -m /home/soft/maven
/home/soft/java
/home/soft/maven
false
$ sh test.sh -j /home/soft/java -m /home/soft/maven -u
/home/soft/java
/home/soft/maven
true
$ sh test.sh -h
test.sh: option requires an argument -- h
Usage:
test.sh [-j JAVA_DIR] [-m MAVEN_DIR]
Description:
JAVA_DIR, the path of java.
MAVEN_DIR, the path of maven.
getopts
后面跟的字符串就是参数列表,每个字母代表一个选项,如果字母后面跟一个:
就表示这个选项还会有一个值,比如上面例子中对应的-j /home/soft/java
和-m /home/soft/maven
。而getopts
字符串中没有跟随:
的字母就是开关型选项,不需要指定值,等同于true/false
,只要带上了这个参数就是true
。
getopts
识别出各个选项之后,就可以配合case
进行操作。操作中,有两个"常量",一个是OPTARG
,用来获取当前选项的值;另外一个就是OPTIND
,表示当前选项在参数列表中的位移。case的最后一项是?
,用来识别非法的选项,进行相应的操作,我们的脚本中输出了帮助信息。
当选项参数识别完成以后,我们就能识别剩余的参数了,我们可以使用shift
进行位移,抹去选项参数。
#!/bin/bash
usage() {
echo "Usage:"
echo " test.sh [-j JAVA_DIR] [-m MAVEN_DIR]"
echo "Description:"
echo " JAVA_DIR, the path of java."
echo " MAVEN_DIR, the path of maven."
exit -1
}
upload="false"
echo $OPTIND
while getopts 'j:m:u' OPT; do
case $OPT in
j) JAVA_DIR="$OPTARG";;
m) MAVEN_DIR="$OPTARG";;
u) upload="true";;
h) usage;;
?) usage;;
esac
done
echo $OPTIND
shift $(($OPTIND - 1))
echo $1
---------------
$ sh test.sh -j /home/soft/java -m /home/soft/maven otherargs
1
5
otherargs
sh test.sh -j /home/soft/java -m /home/soft/maven -u otherargs
1
6
otherargs
在上面的脚本中,我们位移的长度等于case循环结束后的OPTIND - 1
,OPTIND
的初始值为1,当选项参数处理结束后,其指向剩余参数的第一个。getopts在处理参数时,处理带值的选项参数,OPTIND
加2
;处理开关型变量时,OPTIND
则加1。
以上就是对getopts
的简单介绍。
在放一个复杂一点的例子:
optspec=":hv-:"
while getopts "$optspec" optchar; do
case "${optchar}" in
-)
case "${OPTARG}" in
servers=*)
SERVERS=${OPTARG##*=}
;;
data_dir=*)
DATA_DIR=${OPTARG##*=}
;;
data_log_dir=*)
DATA_LOG_DIR=${OPTARG##*=}
;;
log_dir=*)
LOG_DIR=${OPTARG##*=}
;;
conf_dir=*)
CONF_DIR=${OPTARG##*=}
;;
client_port=*)
CLIENT_PORT=${OPTARG##*=}
;;
election_port=*)
ELECTION_PORT=${OPTARG##*=}
;;
server_port=*)
SERVER_PORT=${OPTARG##*=}
;;
tick_time=*)
TICK_TIME=${OPTARG##*=}
;;
init_limit=*)
INIT_LIMIT=${OPTARG##*=}
;;
sync_limit=*)
SYNC_LIMIT=${OPTARG##*=}
;;
heap=*)
HEAP=${OPTARG##*=}
;;
max_client_cnxns=*)
MAX_CLIENT_CNXNS=${OPTARG##*=}
;;
snap_retain_count=*)
SNAP_RETAIN_COUNT=${OPTARG##*=}
;;
purge_interval=*)
PURGE_INTERVAL=${OPTARG##*=}
;;
max_session_timeout=*)
MAX_SESSION_TIMEOUT=${OPTARG##*=}
;;
min_session_timeout=*)
MIN_SESSION_TIMEOUT=${OPTARG##*=}
;;
log_level=*)
LOG_LEVEL=${OPTARG##*=}
;;
*)
echo "Unknown option --${OPTARG}" >&2
exit 1
;;
esac;;
h)
print_usage
exit
;;
v)
echo "Parsing option: '-${optchar}'" >&2
;;
*)
if [ "$OPTERR" != 1 ] || [ "${optspec:0:1}" = ":" ]; then
echo "Non-option argument: '-${OPTARG}'" >&2
fi
;;
esac
done
调用:
- sh
- -c
- "start-zookeeper \
--servers=3 \
--data_dir=/var/lib/zookeeper/data \
--data_log_dir=/var/lib/zookeeper/data/log \
--conf_dir=/opt/zookeeper/conf \
--client_port=2181 \
--election_port=3888 \
--server_port=2888 \
--tick_time=2000 \
--init_limit=10 \
--sync_limit=5 \
--heap=512M \
--max_client_cnxns=60 \
--snap_retain_count=3 \
--purge_interval=12 \
--max_session_timeout=40000 \
--min_session_timeout=4000 \
--log_level=INFO"