使用getopt处理shell脚本的参数

getopt命令并不是bash的内建命令,它是由util-linux包提供的外部命令。相比较bash 的内置命令,getopt不只支持短参-s,还支持--longopt的长参数,甚至支持-longopt的简化参数。getopt可以用于tcsh其它的shell。
现在就以系统自带的帮助文件,说说getopt在bash下的使用技巧。
 
#!/bin/bash  
 
# A small example program for using the new getopt(1) program.  
# This program will only work with bash(1)  
# An similar program using the tcsh(1) script language can be found  
# as parse.tcsh  
 
# Example input and output (from the bash prompt):  
# ./parse.bash -a par1 ‘another arg‘ --c-long ‘wow!*\?‘ -cmore -b " very long "  
# Option a  
# Option c, no argument  
# Option c, argument `more‘  
# Option b, argument ` very long ‘  
# Remaining arguments:  
# --> `par1‘  
# --> `another arg‘  
# --> `wow!*\?‘  
 
# Note that we use `"[email protected]"‘ to let each command-line parameter expand to a   
# separate word. The quotes around `[email protected]‘ are essential!  
# We need TEMP as the `eval set --‘ would nuke the return value of getopt.  
TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \  
     -n ‘example.bash‘ -- "[email protected]"`  
 
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi  
 
# Note the quotes around `$TEMP‘: they are essential!  
eval set -- "$TEMP" 
 
while true ; do  
        case "$1" in 
                -a|--a-long) echo "Option a" ; shift ;;  
                -b|--b-long) echo "Option b, argument \`$2‘" ; shift 2 ;;  
                -c|--c-long)  
                        # c has an optional argument. As we are in quoted mode,  
                        # an empty parameter will be generated if its optional  
                        # argument is not found.  
                        case "$2" in 
                                "") echo "Option c, no argument"; shift 2 ;;  
                                *)  echo "Option c, argument \`$2‘" ; shift 2 ;;  
                        esac ;;  
                --) shift ; break ;;  
                *) echo "Internal error!" ; exit 1 ;;  
        esac  
done  
echo "Remaining arguments:" 
for arg do echo ‘--> ‘"\`$arg‘" ; done 
 getopt 命令的选项说明:
-a 使getopt长参数支持"-"符号打头,必须与-l同时使用
-l 后面接getopt支持长参数列表
-n program如果getopt处理参数返回错误,会指出是谁处理的这个错误,这个在调用多个脚本时,很有用
-o 后面接短参数列表,这种用法与getopts类似
-u 不给参数列表加引号,默认是加引号的(不使用-u选项),例如在加不引号的时候 --longopt "select * from db1.table1" $2只会取到select ,而不是完整的SQL语句。
使用eval 的目的是为了防止参数中有shell命令,被错误的扩展。
实际官方提供的这个语法也不是很简洁,下面提供一个我平时用到的:
 
ARGS=`getopt -a -o I:D:T:e:k:LMSsth -l instence:,database:,table:,excute:,key:,list,master,slave,status,tableview,help -- "[email protected]"`   ###在参数列表做后加入 --
[ $? -ne 0 ] && usage  
#set -- "${ARGS}"  
eval set -- "${ARGS}"                                                    ####这句不可少    ### 长的参数选项最好用=指定 如 --port=22 | ./configure --prefix=/usr/local
 
while true  
do  
        case "$1" in 
        -I|--instence)  
                instence="$2" 
                shift  
                ;;  
        -D|--database)  
                database="$2" 
                shift  
                ;;  
        -T|--table)  
                table="$2" 
                shift  
                ;;  
        -e|--excute)  
                excute="yes" 
                shift  
                ;;  
        -k|--key)  
                key="$2" 
                shift  
                ;;  
        -L|--list)  
                LIST="yes" 
                ;;  
        -M|--master)  
                MASTER="yes" 
                ;;  
        -S|--slave)  
                SLAVE="yes" 
                ;;  
        -A|--alldb)  
                ALLDB="yes" 
                ;;  
        -s|--status)  
                STATUS="yes" 
                ;;  
        -t|--tableview)  
                TABLEVIEW="yes" 
                ;;  
        -h|--help)  
                usage  
                ;;  
        --)  
                shift  
                break 
                ;;  
        esac  
shift  
done 
重点关注一下,esac和done中的shift,还有符号“--”条件下的shift;break操作。

#############################################################################################################################
 bash环境下,以“-”或“--”开头的参数称选项参数。可以使用bash内置命令getopts或外部命令getopt进行传递。getopts的时候可参考《》,以下用getopt的范例进行说明。
一、获取范例
getopt官网:点击
范例下载:
下载文件
点击这里下载文件

二、前提
1、先确定是否增强版的getopt
引用
# getopt -T
# echo $?
4
# getopt -V
getopt (enhanced) 1.1.3

返回结果为4,则为增强版的getopt,否则为旧版本。
2、命令参数
getopt可以为bash提供短选项和长选项的参数引用:
引用
-o 短选项
-l 长选项
-n 脚本命令,若传递参数报错,会报该名字

选项的使用定义规则类似:
引用
ab:c::

意思是:
引用
a 后没有冒号,表示没有可以参数
b 后跟一个冒号,表示有一个必要的参数
c 后跟两个冒号,表示有一个可选的参数
长选项的定义相同,但用逗号分割。

三、示例脚本
截取主要部分:
引用

# 请注意定义方法,以及使用"[email protected]"从bash获取参数,不能使用$*代替,“"”号也不能缺少
TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \
    -n ‘example.bash‘ -- "[email protected]"`

if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi

# 使用eval set分配位置参数,$TEMP必须使用“"”号括住
eval set -- "$TEMP"

#请留意shift需根据是否可接受参数而移动
while true ; do
 case "$1" in
   -a|--a-long) echo "Option a" ; shift ;;
   -b|--b-long) echo "Option b, argument \`$2‘" ; shift 2 ;;
   -c|--c-long) 
     # c 选项带一个可选的参数,若没有指定则为空,请留意后面给予选项参数的写法
     case "$2" in
     "") echo "Option c, no argument"; shift 2 ;;
     *)  echo "Option c, argument \`$2‘" ; shift 2 ;;
     esac ;;
     --) shift ; break ;;
     *) echo "Internal error!" ; exit 1 ;;
     esac
done
#显示除选项参数外的参数
echo "Remaining arguments:"
for arg do echo ‘--> ‘"\`$arg‘" ; done

四、使用
1、第一次
引用
# sh getopt-parse.bash -a "arg1 arg2"
Option a
Remaining arguments:
--> `arg1 arg2‘

可以看到,-a后不能接受选项参数,其会作为普通参数存在。
2、第二次
引用
# sh getopt-parse.bash -b "arg4"
Option b, argument `arg4‘
Remaining arguments:

-b选项可以接受参数。再试试这个:
引用
# sh getopt-parse.bash -b
example.bash:选项需要一个参数 -- b
Remaining arguments:

-b后面跟的是必要参数哦,不能忽略。
3、第三次
引用
# sh getopt-parse.bash -c "arg3"
Option c, no argument
Remaining arguments:
--> `arg3‘

奇怪,-c后已经跟有选项参数,但并没有识别到?再试试:
引用
# sh getopt-parse.bash -c"arg3"
Option c, argument `arg3‘
Remaining arguments:

原来如此,-c和选项参数之间不能有空格。
4、全部一起
引用
# sh getopt-parse.bash -a "arg1 arg2" -c"arg3" -b "arg4" "arg5"
Option a
Option c, argument `arg3‘
Option b, argument `arg4‘
Remaining arguments:
--> `arg1 arg2‘
--> `arg5‘

请注意区分选项参数和普通参数。

五、遗留问题
   长选项使用可选参数会报错,可见:
引用
# sh getopt-parse.bash -c"more"
Option c, argument `more‘
Remaining arguments:
# sh getopt-parse.bash --c-long"more"
example.bash:无法识别的选项“--c-longmore”
Remaining arguments:
# sh getopt-parse.bash --c-long "more"
Option c, no argument
Remaining arguments:
--> `more‘

################################################################
1.单个字符,表示选项,
2.单个字符后接一个冒号:表示该选项后必须跟一个参数。参数在选项后空格隔开。该参数的指针赋给optarg。
3 单个字符后跟两个冒号,表示该选项后非必需跟一个参数。若有参数必须紧跟在选项后不能以空格隔开。该参数的指针赋给optarg。(这个特性是GNU的扩张)。
getopt处理以‘-’开头的命令行参数,如optstring="ab:c::d::",命令行为getopt.exe -a -b host -ckeke -d haha 
在这个命令行参数中,-a和-h就是选项元素,去掉‘-‘,a,b,c就是选项。host是b的参数,keke是c的参数。但haha并不是d的参数,因为它们中间有空格隔开。
还要注意的是默认情况下getopt会重新排列命令行参数的顺序,所以到最后所有不包含选项的命令行参数都排到最后。

时间: 2024-08-24 12:06:46

使用getopt处理shell脚本的参数的相关文章

shell脚本接参数优美用法

shell脚本接参数优美用法 学习 bash shell脚本接参数优美用法 2.1 getopt命令的用法 2.2 示例 1. 示例脚本 2. 转载阅读 1. 示例脚本 #!/usr/bin/env bash#Bash脚本接参数优美用法#Create on 2016-11-18#@author: Chinge_Yang args="$*" function usage(){    echo "Usage: `basename $0` options (-h HOST|-n N

对于shell脚本获取参数的一些小技巧

问题如下: 根据脚本参数的个数$#进行一个循环,在依次输出每个参数$1 $2 $3...... 我有一个循环变量i $i  取到这时的i为1,我想使用这个1再去调用$1,也是就是打印出第一个参数 就是$($i)的意思来取到第几个参数,当然$($i)是不好用的 当时纠结了好久,最后上百度提问,两位高手给出了答案: 1) #!/bin/sh NUMBER=$# echo $NUMBER i=1 while [ $i -le $NUMBER ] do a[$i]=$1 #将数组a[i]赋值为$1,即取

vim编辑器简介;shell脚本的参数;yum仓库配置

1. vim编辑器 命令模式:dd:删除(剪切)光标所在整行:ndd:删除(剪切)光标处开始的n行:yy:复制光标所在整行:nyy:复制从光标开始处的n行:u:撤销上一步的操作:p:将之前删除(dd)或复制(yy)过的数据粘贴到光标后面:输入模式:进入:a或i或o:a:在光标后面以为切换到输入模式:i:在光标当前位置切换到输入模式:o:在光标的下面再创建一个空行:退出到命令模式:Esc键':'或末行模式::w 保存:q 退出:wq! 强制保存退出:q! 强制退出(放弃对文档的修改):set nu

linux shell脚本通过参数名传递参数值

平常在写shell脚本都是用$1,$2....这种方式来接收参数,然而这种接收参数的方式不但容易忘记且不易于理解和维护.Linux常用的命令都可指定参数名和参数值,然而我们怎样才能给自己的shell脚本也采用参数名和参数值这样的方式来获取参数值呢?而不是通过$1,$2这种方式进行获取.下面的例子定义了短参数名和长参数名两种获取参数值的方式.其实是根据getopt提供的特性进行整理而来. #!/bin/sh #说明 show_usage="args: [-l , -r , -b , -w]\ [-

shell脚本 传参数 case for

$ cat openstack_install.sh #!/usr/bin/env bash function usage { echo "Usage:$0 [OPTAION]..." echo "master install openstack master in this system." echo "compute install openstack compute in this system." exit } function proc

shell脚本带参数实例

#!/bin/bashname=$1old=$2if [[ $# -ne 2 ]];then echo "the test must input 2 nu!!"echo $#exit 0fiecho "my name is ${name}!"echo "i'm ${old} yeas old!"if [[ ${old} <30 ]];thenecho "you are so yunng!"elseecho "s

sed如何引用shell脚本的参数

sed -e 's/pattern/ '"$1"' /' file

shell 脚本添加参数小实例

#/bin/bash case [email protected] in-h)         echo 'hi,this is hlep...'        ;;-c)        echo 'chicozy'        ;;-z)        echo 'zhouyin'        ;;--help)        echo 'hi,this is hlep...'        ;;esac

shell脚本编程基础知识

Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言. Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务. Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 Shell.bash是很多linux系统的默认shell. 下面开始写一个范例shell #!/bin/bashecho "Hello World