运行脚本时的命令行参数,如
在Shell脚本中,可以对上面的参数做如下处理
./myscript.sh -a -b arg
在脚本中通常是用case语句处理。我个人比较喜欢的做法:首先尽量使用长参数名(短参数名通常意义不明显,毕竟你的脚本没有这么流行),比如
./myscript --with-ssl=yes --install-dir=../export
再在脚本中通过下面的函数处理参数
################################################################################
# 分析命令行,如果命令行中有选项(作为函数第1个实参):
# --xxx-x-x=vvv
# 则这个函数执行__xxx_x_x=vvv,即,相当于将vvv赋值给__xxx_x_x变量
# 如果命令行中的选项不包含'='号,则这个函数将命令行参数插入第2个实参代表的变量中
# 以供稍后处理
################################################################################
function ParseOption(){
if [ $# -gt 0 ]; then
if [ "${1:0:2}" = "--" ]; then
local key=${1%%=*}
if [ "${key}" != "${1}" ]; then
local value=${1#*=}
key=${key//-/_}
eval ${key}=${value}
return 0
elif [ -n "${key}" ] && [ -n "${2}" ]; then
eval ${2}+=\" ${1}\"
return 0
else
return 1
fi
elif [ -n "${2}" ]; then
eval ${2}+=\" ${1}\"
return 0
else
return 1
fi
else
return 1
fi
}
arguments=
for option in $*
do
ParseOption ${option} arguments
done
arguments可以稍后拿来做case处理,但对于赋值型命令行参数,这种处理方式扩展性非常好。
比如,我们的脚本要跟svn打交道,有下面的语句:
svn update
但我在其它机器上运行这个脚本时,发现它的svn没有安装在系统路径,需要使用全路径引用。我只需要简单的修改这行代码为
${__svn:-svn} update
不用添加任何多余的代码,脚本就可以支持通过命令行参数的方式指定svn路径,即
./myscript --svn=/opt/subversion/bin/svn ...
相当方便。通过这种方式,添加命令行参数的支持不再麻烦,脚本只需要正确使用变量即可。
另外,一些“动态命名”的参数,用case也难以处理,如
./build-tool ... --platforms=st5197,st7105 --st5197-config=st5197_setenv.sh --st7105-config=st7105_setenv.sh
上述命令的意思是,我们的平台指定了st5197和st7105,同时,这两个平台都有预处理脚本,在我们的进行正式工作前要去执行(比如说一些环境变量的设置)。这些脚本的数量不定(对应于--platforms指定的平台数),就是说,--platforms指定了4个平台,后面可能会有4个--{platform}-config(也可能少于4个,表明相应平台不需要预处理脚本);同时,指定的这些参数要能够与相应的平台联系起来,这就是为什么我们在选项命名上与平台关联起来(也就是说,这些选项命名不是预先确定的)。
在Shell脚本中,可以对上面的参数做如下处理
for platform in ${__platforms}
do
#如果命令行指定了参数--{platform}-config=FILE,则在上述ParseOption()里__{platform}_config变量已被赋上值,将这个值转存到platform_config变量里以方便后面引用
eval platform_config='$'__${platform}_config
if [ -n "${platform_config}" ]; then
...
fi
done
可以简单的获取平台对应的config文件名称,并加以处理。