使用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 `"$@"' to let each command-line parameter expand to a
# separate word. The quotes around `$@' 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' -- "$@"`
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 -- "$@"` ###在参数列表做后加入 --
[ $? -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 后跟两个冒号,表示有一个可选的参数
长选项的定义相同,但用逗号分割。
三、示例脚本
截取主要部分:
引用
# 请注意定义方法,以及使用"$@"从bash获取参数,不能使用$*代替,“"”号也不能缺少
TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \
-n 'example.bash' -- "$@"`
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会重新排列命令行参数的顺序,所以到最后所有不包含选项的命令行参数都排到最后。
转载于:https://blog.51cto.com/2242558/1545331
相关文章:

Java基础教程——包装类
Java出道之时,自诩为“纯面向对象的语言”,意思是之前的所谓“面向对象语言”不纯。 但是,有人指责Java也不纯——8种基本类型并非类类型。为此,Java为他们提供可对应的类类型,是为“包装类”。 包装类 Java的八种基本…

linux kernel list_head
Play with kernel list_head, three exampleshttps://www.fatalerrors.org/a/play-with-kernel-list_head-three-examples-of-super-cattle.html一篇介绍linux 内核链表的非常精彩的文章。

oracle rman实时备份吗,ORACLE-RMAN自动备份和恢复
以下介绍的是每周1-6增量备份,每周日全量备份。通过系统启动自动化任务[oracleorcl ~]$ crontab -l10 00 * * 0 /home/scripts/rmanlevel0.sh10 00 * * 1,2,3,4,5,6 /home/scripts/rmanlevel1.sh30 00 * * * /home/oracle/report/awr.sh[oracleorcl ~]$ cat /home…

hdu 5438 Ponds 拓扑排序
Ponds Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid1001&cid621Description Betty owns a lot of ponds, some of them are connected with other ponds by pipes, and there will not be more than o…

CentOS6安装nodejs
Nodejs是JavaScript的一种运行环境,是一个服务端的JavaScript解释器。 NPM是Nodejs的包管理器。 Nodejs包含npm,所以安装完nodejs后npm默认也被安装。 安装步骤: # /usr/local/srcwget http://nodejs.org/dist/v6.7.0/node-v6.7.0-linux-…

Codeforces Round #FF 446 C. DZY Loves Fibonacci Numbers
參考:http://www.cnblogs.com/chanme/p/3843859.html 然后我看到在别人的AC的方法里还有这么一种神方法,他预先设定了一个阈值K,当当前的更新操作数j<K的时候,它就用一个类似于树状数组段更的方法,用一个 d数组去存内容&#x…

Java 基本概念
Java 基本概念 1. Java 语言的优点? 简单、高效 Java 语言与 C 类似,如果用户了解 C 和面向对象的概念,就可以很快编写出 Java 程序;此外,Java 又不同于诸如 C 语言提供的各种各样的方法,它只提供了基本的方法&#x…

list_for_each_safe
list_for_each_safeBidirect-list list_for_each_safe().https://biscuitos.github.io/blog/LIST_list_for_each_safe/

oracle恢复是怎么看进度,Oracle中查看慢查询进度的脚本分享
Oracle一个大事务的sql往往不知道运行到了哪里,可以使用如下sql查看执行进度。代码如下:404_6set linesize 400;H_404_6set pagesize 400;H_404_6col sql_text format a100;H_404_6col opname format a15;H_404_6SELECT se.sid,H_404_6opname,H_404_6TRUNC (sofar / totalwork …

第三周 9.13-9.19
9.13 长春OL。 9.14-9.15 什么都没干。 9.16-9.17 补题。 9.18 什么都没干。 9.19 沈阳OL。 本周就是什么都没干。转载于:https://www.cnblogs.com/Aguin/p/4805509.html

vue-devTools插件安装流程
vue-devTools插件安装流程 本文主要介绍 vue的调试工具 vue-devtools 的安装和使用 工欲善其事, 必先利其器, 快快一起来用vue-devtools来调试开发你的vue项目吧 安装: 1.到github下载:(下载一定要记得是master环境的代码,默认克隆后进入…

基于ipfire的open***功能--client to net (Roadwarrior)配置(一)
Client-to-Net configuration (Roadwarrior)全局配置第一步应该是生成服务证书来激活ipfire上的open***。完成这个后,全局配置就可以使用了。为了激活open***所需的接口,open***服务监听的地方,你需要勾选界面里的方框。如何勾选,…

oracle update from多表性能优化一例
这几天测试java内存数据库,和oracle比较时发下一个update from语句很慢,如下: update business_newset fare1_balance_ratio (select BALANCE_RATIO from bfare2where bfare2.exchange_type business_new.exchange_type andbfa…

Sorry, Sarah
Sorry, Sarah
C#中Winform程序中如何实现多维表头【不通过第三方报表程序】
问题:C#中Winform程序中如何实现多维表头。 在网上搜了很多方法,大多数方法对于我这种新手,看的都不是很懂。最后在新浪博客看到了一篇比较易懂的文章:【DataGridView二维表头与合并单元格】 大体的思路如下: 1.新建一…

斗地主发牌编程PHP,JAVA代码之斗地主发牌详解
package com.oracle.demo01;import java.util.ArrayList;import java.util.Collections;import java.util.HashMap;import java.util.Map;public class Doudizhu {public static void main(String[] args) {//1.创建扑克牌MapMap pookernew HashMap();//创建所有key所在的容器A…

2022-2028年中国自动化设备市场研究及前瞻分析报告
【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新(交付时间约3个工作日) 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国自动化设备行业市场行业相关概述、中国自动化设备行业市场行业运行环境、分析了中国自动化…

转发:某些函数需要将其一个或多个实参连同类型不变地转发给其他函数
16.47 编写你自己版本的翻转函数,通过调用接受左值和右值引用参数的函数来测试它。 #include<iostream> #include<string> #include<utility> using namespace std;template <typename T> int compare(const T &a ,const T &b) {if…

pycharm远程调试或运行代码
第一步:开始 第二步:设置远程服务器 第三步,查看 第四步,选择解释器,和指定文件映射路径(相对上一步指定的相对路径) 转载于:https://www.cnblogs.com/jeshy/p/11182359.html
LTE随机接入过程
随机接入的基本流程 Msg3和Msg4只有基于竞争的随机接入才存在,之所以叫Msg3/Msg4是因为不同的随机接入情况,Msg3/Msg4的消息不相同(本文稍后介绍)。 下图中的参数<ra-ResponseWindowSize>和<mac-ContentionResolutionTimer>来自SIB2中的rach…

workday与oracle,workingday与workday的区别 – 手机爱问
2005-04-11for的用法FOR到底应该怎么用?对于for的用法的确很多,可用作介词和连词,介词用法尤为丰富。以下详细列出了用法和句例,供你参考。for 1 preposition1used to say who is intended to g…

OGRE 2.1 Windows 编译
版权所有,转载请注明链接 OGRE 2.1 Windows 编译 环境: Windows 7 64Bit Visual Studio 2012 OGRE 2.1 CMake 2.8.12.1 OGRE: OGRE官方推出了最新的OGRE2.1版本,链接地址: https://bitbucket.or…

IDEA集成Docker插件实现一键自动打包部署微服务项目
一. 前言 大家在自己玩微服务项目的时候,动辄十几个服务,每次修改逐一部署繁琐不说也会浪费越来越多时间,所以本篇整理通过一次性配置实现一键部署微服务,实现真正所谓的一劳永逸。 二. 配置服务器 1. Docker安装 服务器需要安…

PHP的学习--PHP的引用
引用是什么 在 PHP 中引用意味着用不同的名字访问同一个变量内容。这并不像 C 的指针,替代的是,引用是符号表别名。注意在 PHP 中,变量名和变量内容是不一样的,因此同样的内容可以有不同的名字。最接近的比喻是 Unix 的文件名和文…

谈一谈浏览器解析CSS选择器的过程【前端每日一题-6】
谈一谈浏览器解析CSS选择器的过程? 这是一道发散题,可以根据自己的理解自行解答。 在开始前,我们必须了解一个真相:为什么排版引擎解析 CSS 选择器时一定要从右往左解析? 简单的来说:浏览器从右到左进行查找…

LTE: MIB和SIB,小区选择和重选规则
LTE 中MIB/SIB内容可以参考:https://blog.csdn.net/wowricky/article/details/51348613 MIB/SIB的详细内容参考下面两张图 MIB,SIB1,SIB2 可以关注下小区选择的参数,用特殊颜色表示 36.304 - 5.2.3.2 Cell Selection Criterion S准则,需要…

linux 生成dll文件,Linux和Windows平台 动态库.so和.dll文件的生成
Linux动态库的生成1、 纯cpp文件打包动态库将所有cpp文件和所需要的头文件放在同一文件夹,然后执行下面命令gcc -shared - fpic *.c -o xxx.so;g -stdc17 - fpic *.cpp -o xxx.so;[C17标准,需要高版本gcc,本人采用gcc …

Form表单提交前进行JS验证的3种方式
1. 提交按钮的onclick事件中验证 <script type"text/javascript"> function check(form) { return true; }</script> <form> <input type"submit" name"submit1" value"登陆" οnc…

2022-2028年中国椎间孔镜行业市场研究及前瞻分析报告
【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新(交付时间约3个工作日) 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国椎间孔镜行业市场行业相关概述、中国椎间孔镜行业市场行业运行环境、分析了中国椎间孔镜行…

mysql 错误:1166 解决办法
原因:检查字段里面是不是有空格,去掉就可以了转载于:https://www.cnblogs.com/zhizhan/p/3950453.html