getopt命令并不是bash的内建命令,它是由util-linux包提供的外部命令。相比较bash 的内置命令,getopt不只支持短参-s,还支持--longopt的长参数,甚至支持-longopt的简化参数。getopt可以用于tcsh其它的shell。

现在就以系统自带的帮助文件,说说getopt在bash下的使用技巧。

 

 
    
  1. #!/bin/bash  
  2.  
  3. # A small example program for using the new getopt(1) program.  
  4. # This program will only work with bash(1)  
  5. # An similar program using the tcsh(1) script language can be found  
  6. # as parse.tcsh  
  7.  
  8. # Example input and output (from the bash prompt):  
  9. # ./parse.bash -a par1 'another arg' --c-long 'wow!*\?' -cmore -b " very long "  
  10. # Option a  
  11. # Option c, no argument  
  12. # Option c, argument `more'  
  13. # Option b, argument ` very long '  
  14. # Remaining arguments:  
  15. # --> `par1'  
  16. # --> `another arg'  
  17. # --> `wow!*\?'  
  18.  
  19. # Note that we use `"$@"' to let each command-line parameter expand to a   
  20. # separate word. The quotes around `$@' are essential!  
  21. # We need TEMP as the `eval set --' would nuke the return value of getopt.  
  22. TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \  
  23.      -n 'example.bash' -- "$@"`  
  24.  
  25. if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi  
  26.  
  27. # Note the quotes around `$TEMP': they are essential!  
  28. eval set -- "$TEMP" 
  29.  
  30. while true ; do  
  31.         case "$1" in 
  32.                 -a|--a-long) echo "Option a" ; shift ;;  
  33.                 -b|--b-long) echo "Option b, argument \`$2'" ; shift 2 ;;  
  34.                 -c|--c-long)  
  35.                         # c has an optional argument. As we are in quoted mode,  
  36.                         # an empty parameter will be generated if its optional  
  37.                         # argument is not found.  
  38.                         case "$2" in 
  39.                                 "") echo "Option c, no argument"; shift 2 ;;  
  40.                                 *)  echo "Option c, argument \`$2'" ; shift 2 ;;  
  41.                         esac ;;  
  42.                 --) shift ; break ;;  
  43.                 *) echo "Internal error!" ; exit 1 ;;  
  44.         esac  
  45. done  
  46. echo "Remaining arguments:" 
  47. 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命令,被错误的扩展。
实际官方提供的这个语法也不是很简洁,下面提供一个我平时用到的:

 

 
    
  1. ARGS=`getopt -a -o I:D:T:e:k:LMSsth -l instence:,database:,table:,excute:,key:,list,master,slave,status,tableview,help -- "$@"`  
  2. [ $? -ne 0 ] && usage  
  3. #set -- "${ARGS}"  
  4. eval set -- "${ARGS}" 
  5.  
  6. while true  
  7. do  
  8.         case "$1" in 
  9.         -I|--instence)  
  10.                 instence="$2" 
  11.                 shift  
  12.                 ;;  
  13.         -D|--database)  
  14.                 database="$2" 
  15.                 shift  
  16.                 ;;  
  17.         -T|--table)  
  18.                 table="$2" 
  19.                 shift  
  20.                 ;;  
  21.         -e|--excute)  
  22.                 excute="yes" 
  23.                 shift  
  24.                 ;;  
  25.         -k|--key)  
  26.                 key="$2" 
  27.                 shift  
  28.                 ;;  
  29.         -L|--list)  
  30.                 LIST="yes" 
  31.                 ;;  
  32.         -M|--master)  
  33.                 MASTER="yes" 
  34.                 ;;  
  35.         -S|--slave)  
  36.                 SLAVE="yes" 
  37.                 ;;  
  38.         -A|--alldb)  
  39.                 ALLDB="yes" 
  40.                 ;;  
  41.         -s|--status)  
  42.                 STATUS="yes" 
  43.                 ;;  
  44.         -t|--tableview)  
  45.                 TABLEVIEW="yes" 
  46.                 ;;  
  47.         -h|--help)  
  48.                 usage  
  49.                 ;;  
  50.         --)  
  51.                 shift  
  52.                 break 
  53.                 ;;  
  54.         esac  
  55. shift  
  56. done 

重点关注一下,esac和done中的shift,还有符号“--”条件下的shift;break操作。