Bash Getopts - 让你的脚本支持命令行参数

Bash Getopts - 让你的脚本支持命令行参数

以前我总想知道如何为我的Bash脚本创建命令行参数。经过搜索,我发现了2个函数可以处理这个问题,getopt 函数和 getopts 函数。我无意争论哪一个函数更好的。getopts 是一个shell内建命令,而且似乎比 getopt 更容易实现这个功能,所以在这篇文章里我准备讲讲getopts。

bash getopts

开始的时候,我只试着处理传递给脚本的命令行参数。最后,我添加了另外一些有用的功能函数,使得这个脚本可以成为其他任何交互式脚本处理命令行的开始模板。我还添加了一个纯文本格式的帮助函数,让脚本更加容易阅读。

与其来一长段文字解释 getopts 在bash中是如何工作的,我认为不如直接来一个能工作的脚本更让人觉得轻松一些。


  1. #!/bin/bash
  2.  
  3. ######################################################################
  4. #This is an example of using getopts in Bash. It also contains some
  5. #other bits of code I find useful.
  6. #Author: Linerd
  7. #Website: http://tuxtweaks.com/
  8. #Copyright 2014
  9. #License: Creative Commons Attribution-ShareAlike 4.0
  10. #http://creativecommons.org/licenses/by-sa/4.0/legalcode
  11. ######################################################################
  12.  
  13. #Set Script Name variable
  14. SCRIPT=`basename ${BASH_SOURCE[0]}`
  15.  
  16. #Initialize variables to default values.
  17. OPT_A=A
  18. OPT_B=B
  19. OPT_C=C
  20. OPT_D=D
  21.  
  22. #Set fonts for Help.[译注: 这里tput用来更改终端文本属性,比如加粗,高亮等]
  23. NORM=`tput sgr0`
  24. BOLD=`tput bold`
  25. REV=`tput smso`
  26.  
  27. #Help function
  28. function HELP {
  29. echo -e \\n"Help documentation for ${BOLD}${SCRIPT}.${NORM}"\\n
  30. echo -e "${REV}Basic usage:${NORM} ${BOLD}$SCRIPT file.ext${NORM}"\\n
  31. echo "Command line switches are optional. The following switches are recognized."
  32. echo "${REV}-a${NORM} --Sets the value for option ${BOLD}a${NORM}. Default is ${BOLD}A${NORM}."
  33. echo "${REV}-b${NORM} --Sets the value for option ${BOLD}b${NORM}. Default is ${BOLD}B${NORM}."
  34. echo "${REV}-c${NORM} --Sets the value for option ${BOLD}c${NORM}. Default is ${BOLD}C${NORM}."
  35. echo "${REV}-d${NORM} --Sets the value for option ${BOLD}d${NORM}. Default is ${BOLD}D${NORM}."
  36. echo -e "${REV}-h${NORM} --Displays this help message. No further functions are performed."\\n
  37. echo -e "Example: ${BOLD}$SCRIPT -a foo -b man -c chu -d bar file.ext${NORM}"\\n
  38. exit 1
  39. }
  40.  
  41. #Check the number of arguments. If none are passed, print help and exit.
  42. NUMARGS=$#
  43. echo -e \\n"Number of arguments: $NUMARGS"
  44. if [ $NUMARGS -eq 0 ]; then
  45. HELP
  46. fi
  47.  
  48. ### Start getopts code ###
  49.  
  50. #Parse command line flags
  51. #如果选项需要后跟参数,在选项后面加":"
  52. #注意"-h"选项后面没有":",因为他不需要参数。选项字符串最开始的":"是用来去掉来自getopts本身的报错的,同时获取不能识别的选项。(译注:如果选项字符串不以":"开头,发生错误(非法的选项或者缺少参数)时,getopts会向错误输出打印错误信息;如果以":"开头,则不会打印[在man中叫slient error reporting],同时将出错的选项赋给OPTARG变量)
  53.  
  54. while getopts :a:b:c:d:h FLAG; do
  55. case $FLAG in
  56. a) #set option "a"
  57. OPT_A=$OPTARG
  58. echo "-a used: $OPTARG"
  59. echo "OPT_A = $OPT_A"
  60. ;;
  61. b) #set option "b"
  62. OPT_B=$OPTARG
  63. echo "-b used: $OPTARG"
  64. echo "OPT_B = $OPT_B"
  65. ;;
  66. c) #set option "c"
  67. OPT_C=$OPTARG
  68. echo "-c used: $OPTARG"
  69. echo "OPT_C = $OPT_C"
  70. ;;
  71. d) #set option "d"
  72. OPT_D=$OPTARG
  73. echo "-d used: $OPTARG"
  74. echo "OPT_D = $OPT_D"
  75. ;;
  76. h) #show help
  77. HELP
  78. ;;
  79. \?) #unrecognized option - show help
  80. echo -e \\n"Option -${BOLD}$OPTARG${NORM} not allowed."
  81. HELP
  82. #在这里如果你不想打印完整的帮助信息,只想显示简单的错误信息,去掉上面的两行,同时使用下面的两行。
  83. #echo -e "Use ${BOLD}$SCRIPT -h${NORM} to see the help documentation."\\n
  84. #exit 2
  85. ;;
  86. esac
  87. done
  88.  
  89. shift $((OPTIND-1)) #This tells getopts to move on to the next argument.
  90.  
  91. ### End getopts code ###
  92.  
  93.  
  94. ### Main loop to process files ###
  95.  
  96. #这里你可以用你的脚本处理逻辑来替代。这个例子只是在终端中打印文件的文件名和后缀名。你可以把任意其他的文件处理任务放到这个while-do循环中。
  97.  
  98. while [ $# -ne 0 ]; do
  99. FILE=$1
  100. TEMPFILE=`basename $FILE`
  101. #TEMPFILE="${FILE##*/}" #另外一种获取不带后缀的文件名的方法。
  102. FILE_BASE=`echo "${TEMPFILE%.*}"` #file without extension
  103. FILE_EXT="${TEMPFILE##*.}" #file extension
  104.  
  105.  
  106. echo -e \\n"Input file is: $FILE"
  107. echo "File withouth extension is: $FILE_BASE"
  108. echo -e "File extension is: $FILE_EXT"\\n
  109. shift #Move on to next input file.
  110. done
  111.  
  112. ### End main loop ###
  113.  
  114. exit 0

将上面的代码复制到你的文本编辑器里,然后保存到你的可执行路径下。我将这个脚本命名为 options 并保存到 /home/linerd/bin 路径下。保存之后记得给你的脚本添加可执行权限。


  1. chmod +x ~/bin/options

现在脚本已经可以运行了。试试用 -h 参数来打印帮助信息吧。


  1. options -h

遇到不支持的选项,脚本同样可以给出提示,并打印帮助信息。


  1. options -z

最后,getopts可以以任意的顺序处理你给的命令行参数。唯一的限制是你要处理的文件必须放在所有参数的最后。


  1. options -d bar -c chu -b man -a foo example1.txt example2.txt

现在你可以从这些例子里看到如何通过命令行参数给脚本里的变量赋值。这个脚本里除了getopts还有很多其他的东西,但是我认为这些就足以成为一个新脚本的开头模板了。如果你有兴趣更深入地学习bash的getopts,你可以找找深埋在man page的“Builtins”这一节里的文档,也可以从 Bash Reference Manual 找到信息。

接下来呢?

你会用getops来干什么呢?在评论里告诉我吧。

原文发布时间:2014-06-16

本文来自云栖合作伙伴“linux中国”

时间: 2024-10-30 21:54:30

Bash Getopts - 让你的脚本支持命令行参数的相关文章

mysql-怎样让程序支持命令行操作

问题描述 怎样让程序支持命令行操作 怎样编写支持命令行的程序,比如像mysql,gcc之类的为什么可以通过命令行可以进行操作?我的想法是,程序运行后开启一个线程不断监听键盘的输入,但是这样程序必须启动后才能执行这些命令.但是像gcc之类的可以直接执行命令 啊.还是和系统的shell有关呢. 解决方案 交互式编程,不要想的太偏激 解决方案二: 就是读取命令行输入,然后执行对应的逻辑,执行完了,就继续等待后一个命令的输入. 解决方案三: 就是读取命令行输入,然后执行对应的逻辑,执行完了,输出到控制台

shell命令行参数-Linuxshell脚本中调用可执行程序命令行参数出现丢失错误

问题描述 Linuxshell脚本中调用可执行程序命令行参数出现丢失错误 #!/bin/bash If [$1 == "-i"] then TM_demo $1 $2 fi If [$1 == "-f"] then TM_demo $1 $2 $3 $4 fi 在linux执行的时候./a.sh -f data,出现 [:丢失了"]",大神帮帮忙! 解决方案 [和]不是shell的meta character,所以需要跟其它标识符用blank/s

IBM Key Management工具(iKeyMan)脚本吃掉%*$*无法接收命令行参数之解

http://www.java2class.net/bbs/viewthread.php?tid=230   iKeyman工具是一个图形化用户界面的数字证书管理工具.通过它可以创建一个新的密钥库.测试数字证书.增加CA根到密钥库.从一个密钥库拷贝证书到另一个密钥库,以及从CA机构请求和接收数字证书.设置默认的密钥.更改密码等等. 但是由于IBM产品中所附带的脚本中对接收命令行的参数没有进行有效的处理,以致于想通过命令行进行传递定制的参数无法顺利进行. 对于AIX.Linux.Solaris可以

.NET Core采用的全新配置系统[5]: 聊聊默认支持的各种配置源[内存变量,环境变量和命令行参数]

较之传统通过App.config和Web.config这两个XML文件承载的配置系统,.NET Core采用的这个全新的配置模型的最大一个优势就是针对多种不同配置源的支持.我们可以将内存变量.命令行参数.环境变量和物理文件作为原始配置数据的来源,如果采用物理文件作为配置源,我们可以选择不同的格式(比如XML.JSON和INI等) .如果这些默认支持的配置源形式还不能满足你的需求,我们还可以通过注册自定义ConfigurationSource的方式将其他形式数据作为我们的配置来源. [ 本文已经同

让WPF窗体程序支持命令行方式运行的三种方式

有的时候,我们希望窗体程序也能接受命令行参数,以Console的方式运行.但是实现起来却要一些小技巧才能做到.如果做一个WPF程序,在Window的Loaded事件里写这样的语句: Console.WriteLine("Hello word."); 然后从CMD运行之.会发现这个语句根本没有输出出来.如图1所示. 图1. 从命令行运行Wpf程序 对于这个问题有三个解决方案.三个方案各有优缺点,请酌情选择. 1.使用more命令:这种方案不需要修改任何代码,只要在从命令行运行时加个 &q

Ghost命令行参数一览表

许多人都听说过或用过Norton Ghost这个软件,然而由于它的界面全是英文的,导致许多国内网友为此而头痛.下面以它的7.0版为例,提供了Ghost的命令行参数. /?或/H:查看帮助. -CLONE:克隆. -IA:对所有分区中的扇区进行映象. -ID:对整个磁盘(包括未分区空间)进行复制. -IR:和ID一样,但不将分区调整为扇区界限. -IB:只复制磁盘的启动扇区. -IAL:对LINUX分区进行整个复制,对其它分区则用正常方法. -OR:覆盖空间并进行完整性检查. -NOLILO:复制

php 命令行参数详解及应用

命令行|详解 大家知道,php是一种PHP是一个基于服务端来创建动态网站的脚本语言,您可以用PHP和HTML生成网站主页.当用户打开php页面时,服务端便执行PHP的命令并将执行结果发送至用户的浏览器中,这类似于ASP和CoildFusion,PHP可以运行在WINDOWS和多种版本的UNIX上.除了能够操作您的页面外,PHP还能发送HTTP的标题.您可以设置cookie,管理数字签名和重定向用户,而且它提供了极好的连通性到其它数据库(还有ODBC),集成各种外部库来做用PDF文档解析XML的任

WinRAR命令行参数整理汇集

WinRAR支持命令行执行压缩与解压缩等,而且就一个rar.exe就能支持图形界面的很多操作,特别方便远程管理等 我的实例: 将D:/wk.doc压缩为:final.rar d:/winrar/rarad:/final.rard:/wk.doc 将final.rar中的wk.doc解压到F:盘 rared:/final.rarF: 将final.rar转换成自解压文件 rarsfinal,rar(默认转换到同级目录下了) 给自解压文件(.exe)添加注释(设置默认解压路径等) rarc-zwk.

如何分析命令行参数

如何分析命令行参数     GNU/Linux的命令行选项有两种类型:短选项和长选项,前者以 '-' 作为前导符,后者以 '--' 作为前导符.     比如有一个命令: $ myprog -a vv --add -b --file a.txt b.txt - -- -e c.txt     在GNU/Linux系统,对这种情况的一种合理解释是:     a是短选项,带一个参数vv:     add是长选项,无参数:     b是短选项,无参数:     file是长选项,带一个参数a.txt: