在Shell脚本中处理命令行参数

1 篇文章 0 订阅
1 篇文章 0 订阅
运行脚本时的命令行参数,如
./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文件名称,并加以处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值