目录

简介

getopt

简介

支持选项

用法

getopt optstring parameters

getopt [options] [--]

getopt [options] -o|--options [options] [--]

在shell中使用它

getopts

简介


简介

我们通常在编写shell脚本时简单的方式是通过参数的方式来取到我们想要的参数,如:

#!/bin/bashSYSCODE=$1
APP_NAME=$2
MODE_NAME=$3

但是这有一个问题,就是参数的位置是固定的,倘若用户在调用脚本时参数位置不固定那么就会出现问题,这种方法一般只适用于一两个参数的情况,我们可以使用更高阶的方案,在Linux中提供了两个命令:getopt与getopts,getopts是getopt更高阶的命令,我们先从最简单的介绍,先从getopt开始介绍

getopt

简介

getopt是linux下一个用于解析选项参数的命令行工具

支持选项

选项名 作用
-a, --alternative 允许长选项以 - 开始
-h, --help 用法指南
-l, --longoptions <长选项> 要识别的长选项
-n, --name <程序名> 将错误报告给的程序名
-o, --options <选项字符串> 要识别的短选项
-q, --quiet 禁止 getopt(3)的错误报告
-Q, --quiet-output 无正常输出
-s, --shell <shell> 设置 shell 引用规则
-T, --test 测试 getopt(1) 版本
-u, --unquoted 不引用输出
-V, --version 输出版本信息

用法

getopt optstring parameters

示例:

$ getopt abcd -a -b -c -d
-a -b -c -d --

上面的abcd每一个单词都视为一个短命令,getopt会拆分成:a、b、c、d

$ getopt abcd -a -b -c -d -h
getopt: invalid option -- 'h'-a -b -c -d --

如果我们期望某个选项需要一个输入值,那么可以在这个选项的后面加上":"

示例:

$ getopt ab:cd -a -b this -c -d-a -b this -c -d --

可以看到b后面跟了一个:符号,这个符号的作用是代表这个选项是一个需要输入值的选项,如果不给就会报错:

$ getopt ab:cd -b
getopt: option requires an argument -- 'b'--

需要注意如果你没有给这个选项一个参数的情况下后面跟了一个选项,那么这个选项会被视为参数:

$ getopt ab:cd -b -d-b -d --

也就是说当你这个选项定义为需要输入参数时它会读取这个选项空格后的一个字符串,以空格分隔作为它的输入参数

如果你想这个选项可有输入值也可以没有输入值那么可以使用"::"符号

$ getopt ab::cd -b-b  --

getopt [options] [--] <optstring> <parameters>

示例:

$ $ getopt -q -- abcd -a -b -c -d -e-a -b -c -d --

上面示例示范了一个-q选项,禁止getopt产生错误报告,可以看到-e并不存在于我们定义的短命令之中,但是这次它没有报错,当然我们也可以使用-n来改变报错文件名:

getopt -n test.sh -- abcd -a -b -c -d -e
test.sh: invalid option -- 'e'-a -b -c -d --

可以看到出错的文件名从getopt变成了test.sh

getopt [options] -o|--options <optstring> [options] [--] <parameters>

示例:

getopt -q -o abcd -l arg1,arg2,arg3 -- -a -b -c --arg1 --arg2 --arg3-a -b -c --arg1 --arg2 --arg3 --

这种方案是可以使用多个选项组合,这里我们也使用了长选项

需要值得注意的是,长命令是使用","符号分割的,并且在给选项时需要使用"--"

长选项包含输入值的方法如下:

$ getopt -o abcd -l arg1:,arg2::,arg3 -- -a -b -c --arg1 test --arg2 --arg3-a -b -c --arg1 'test' --arg2 '' --arg3 --

与短命令一样使用的是":"符号

同时可以看到输出后面跟了--,--后面的代表的是没有被绑定的参数选项,比如:

$ getopt -o abcd -l arg1:,arg2::,arg3 -- -a -b -c --arg1 test --arg2 --arg3 test111-a -b -c --arg1 'test' --arg2 '' --arg3 -- 'test111'

可以看到我们增加了一个没有任何意义的参数值,test111,它被输出到了--符号的后面,最终我们解析时可以通过解析--后面的字符串来取到一些信息来做响应的操作

当然你也可以主动使用--来让后面的字符变成特殊参数:

$ getopt -o abcd -l arg1:,arg2::,arg3 -- -a -b -c --arg1 test --arg2 --arg3 -t
getopt: invalid option -- 't'-a -b -c --arg1 'test' --arg2 '' --arg3 --

可以看到-t报错了,因为没有这个短命令,但是如果我们主动使用--就会把它变成特殊参数:

$ getopt -o abcd -l arg1:,arg2::,arg3 -- -a -b -c --arg1 test --arg2 --arg3 -- -t-a -b -c --arg1 'test' --arg2 '' --arg3 -- '-t'

在shell中使用它

先来看一段简单的代码示例:

#/bin/bash
set -- $(getopt ab:cd "$@")
while [ -n "$1" ]
docase "$1" in-a) echo "Found the -a option";;-b) par="$2"echo "Found the -b option,par = $par"shift;;-c) echo "Found the -c option";;-d) echo "Found the -d option";;--) shiftbreak ;;*) echo "$1 is not option";;
esacshift
donecount=1
for param in "$@"
doecho "Parameter #$count: $param"count=$[ $count + 1 ]
done

这里一步一步解释一下上面每段代码的含义,首先第一段代码:

set -- $(getopt ab:cd "$@")

学过shell的都知道,在shell里简单的参数变量可以通过如下方式获取:

at = $1

上面的--符号就是将getopt的输出按空格为分割顺序替换到这个里面去,$@符号是代表输入参数字符串

如:

$ form.sh -a -b -c

其中的-a -b -c会在进入shell的时候写入到@这个变量里去了,然后我们在将它取出作为getopt的参数执行一次,然后在替换到$1、$2里面去

-a -b -c 就等于:$1、$2、$3

如下这段代码也比较简单:

while [ -n "$1" ]
docase "$1" in-a) echo "Found the -a option";;-b) par="$2"echo "Found the -b option,par = $par"shift;;-c) echo "Found the -c option";;-d) echo "Found the -d option";;--) shiftbreak ;;*) echo "$1 is not option";;
esacshift
done

这段代码就是使用了while、case、shift的方式来实现的

首先刚刚执行set指令之后-a、-b、-c已经顺序写入到$1、$2里了,我们这里是先判断$1是否为空,用-n指令来判断,如果为空则逻辑false,那么就会跳出while

while [ -n "$1" ]

case的特性是匹配到一次之后会自动跳转到esac里,而shift的特性是将参数向前挪移一步,如:

$1、$2、$3,执行一次shift指令之后会将2、3向前挪移,2变成1,3变成2,而1会被丢弃

然后case会根据字符串)来比对,如果通用可以用*

然后在--符号里跳出,这个是因为最开始我们说过,一些特殊参数会被getopt输出到--后面,所以当遇到--的时候代表已经到了选项尾部了,那么挪移一步并跳出去

case "$1" in-a) echo "Found the -a option";;-b) par="$2"echo "Found the -b option,par = $par"shift;;-c) echo "Found the -c option";;-d) echo "Found the -d option";;--) shiftbreak ;;*) echo "$1 is not option";;
esacshift

当跳出去之后来到了这里:

count=1
for param in "$@"
doecho "Parameter #$count: $param"count=$[ $count + 1 ]
done

那么这里我们就可以去取到所有的参数了,这里利用了for in的方式去把@里的数据看作为列表,然后去取,在for里如果是字符串则按空格作为分割,然后取到以后输出就可以了

这里的跳两次是为了把输入值跳出去:

-b) par="$2"echo "Found the -b option,par = $par"shift;;

如-a test,那么执行shift之后test就位于$1了,显然这是不对的,因为test是输入值,所以这里shift一次之后在esac里在shift一次就是两次,就跳过了输入值

最终执行结果:

$ ./form.sh -a -b test fassfa -c -d fwqgqwg
Found the -a option
Found the -b option,par = test
Found the -c option
Found the -d option
Parameter #1: fassfa
Parameter #2: fwqgqwg

getopts

简介

getopts不同于getopt,它没有提供那么多选项,也没有那么多种用法,它只有一种用法:getopts option_string variable ,且它是专门为shell提供的,并且它更加的灵活,先来看一段简单的代码示例:

#!/bin/bashwhile getopts "a:" opt; docase $opt ina)echo "this is -a the arg is ! $OPTARG";;\?)echo "Invalid option: -$OPTARG";;esac
done

运行输出:

$ ./form.sh -a hello
this is -a the arg is ! hello

与之前的getopt对比是不是变得更加简洁了?我们不需要去使用set命令以及shift命令了,这些getopts会为我们做好,它会自动去读输入参数,同时在执行的时候会产生两个变量:

OPTIND 和 OPTARG,OPTIND为下一个要处理的参数索引,当调用getopts时如果发现OPTIND索引处的选项有输入值则设置OPTARG并返回true即便没有输入值若索引处存在选项也会返回true,同时为OPTIND递增1,这也是为什么它一般用在while的原因

OPTIND在最初shell就会设置这个值,它不是getopts设置的,而是shell为了支持getopts而在最初就会设置它

while getopts "a:" opt; do

这段代码也很简单,这里就是对opt作为列表进行遍历,opt在shell里为参数列表,同理你不使用getopt说这些你用opt也是一样可以实现选项功能的:

#!/bin/bash
echo "opt:" ${opt}
for opt; docase $opt ina)echo "a ";;b)echo "b ";;*)echo "other " ;;esac
done

同时getopts里是没有-q选项的,如果你想屏蔽错误则可以在选项字符串的前面加上:

#!/bin/bashwhile getopts ":a:" opt; docase $opt ina)echo "this is -a the arg is ! $OPTARG";;\?)echo "Invalid option: -$OPTARG";;esac
done

当你在前面加上:之后当你输入没有注册的选项时也不会报错,如果没有则会产生一个错误并设置输出符号为\?,同时OPTARG就会设置为错误选项

最后补充一点,case里也是支持|符号的,比如:-a|-b)这样的方式,如果是-a或者-b都执行这条指令

Linux下Shell脚本命令行参数:getopt、getopts用法相关推荐

  1. linux shell运行脚本命令行参数,shell脚本命令行参数简介

    之所以用到命令行参数,关键在于shell脚本需要与运行脚本的人员进行交互. bash shell提供了命令行参数添加在命令后面的数据值).命令行选项修改命令行为的单字符值)和直接读取键盘输入. 1.命 ...

  2. linux的shell命令行参数,shell脚本命令行参数简介

    之所以用到命令行参数,关键在于shell脚本需要与运行脚本的人员进行交互. bash shell提供了命令行参数添加在命令后面的数据值).命令行选项修改命令行为的单字符值)和直接读取键盘输入. 1.命 ...

  3. bash/shell 解析命令行参数工具:getopts/getopt

    转载自:https://my.oschina.net/leejun2005/blog/202376 bash 脚本中,简单点的参数选项,我们可以直接用位置参数 $1 $2 这样来获取处理了,例如下面这 ...

  4. Linux下shell脚本/Makefile编写

    Linux下shell脚本/Makefile编写 一.基本概念 代码变成可执行文件,叫做编译(compile):先编译这个,还是先编译那个(即编译的安排),叫做构建(build). make只是一个指 ...

  5. linux shell脚本攻略_(python)Linux下shell脚本监控Tomcat的状态并实现自动启动步骤...

    今天为大家带来的内容是:(python)Linux下shell脚本监控Tomcat的状态并实现自动启动步骤 本文内容主要介绍了Linux下shell脚本监控Tomcat的状态并实现自动启动的步骤,文章 ...

  6. Linux下Shell脚本实战之监测磁盘空间

    Linux下Shell脚本实战之监测磁盘空间 一.脚本目的及要求 二.脚本内容 三.运行脚本 一.脚本目的及要求 (1) 监控/home下每各个用户目录的占用磁盘大小 (2) 监控/var/log下前 ...

  7. Linux下shell脚本之双色球摇号脚本

    Linux下shell脚本之双色球摇号脚本 一.脚本要求 二.脚本内容 三.运行脚本 一.脚本要求 二.脚本内容 三.运行脚本 一.脚本要求 1.编写脚本Lottery.sh,模拟摇号过程 2.6位数 ...

  8. Linux下shell脚本实战之批量新建用户

    Linux下shell脚本实战之批量新建用户 一.脚本要求 二.脚本内容 三.运行脚本 一.脚本要求 二.脚本内容 三.运行脚本 一.脚本要求 1.使用提供的user.txt用户列表 2.批量新建us ...

  9. linux下shell脚本启动其他可执行程序

    linux下shell脚本启动其他可执行程序 零.前言 一.C++代码 二.shell脚本 三.shell运行效果 零.前言 linux下的项目中经常需要使用shell脚本去启动其他程序的操作,下面是 ...

最新文章

  1. mysql 源码安装 5.6.21_Mysql5.6.21源码安装
  2. openstack e版创建instance整个流程
  3. Java的知识点28——文件编码、IO流的实例
  4. 推荐VS2008插件CodeRush Xpress for C#
  5. NSInteger与int的区别
  6. JAVA笔记(运算符)
  7. 开发 Sublime Text 3 插件简易教程
  8. Applese 填数字
  9. flash socket通信问题
  10. 初识Sentinel
  11. JQuery对象与DOM对象
  12. swift5 字符串格式化保留2 位,缺0自动补0
  13. [Windows] 在 Microsoft Docs 网站中挖掘 MVVM 的各种学习资源
  14. 2 CO配置-企业结构-定义-维护成本控制范围(Controlling Area)
  15. 关于Zookeeper的几个问题
  16. Bootstrap表单的默认布局
  17. 苹果iPhone SE 2概念视频放出:全面屏的小屏机
  18. 获取请求消息行信息案例代码
  19. 2011下半年信息系统项目管理师考后感
  20. LCD12864 并口和串口通用程序

热门文章

  1. 哈理工计算机学院学生会技术部,计算机与信息学院学生会简介
  2. android内存泄漏原因分析,Android 内存泄漏案例分析总结(Handler)
  3. cesium 加载Googl式的切片
  4. python樱桃小丸子_appium+python自动化框架搭建
  5. android socket第三方库,OkSocket 一个Android轻量级Socket通讯框架
  6. php中mysql_affected_rows()更新记录返回0_php中mysql_affected_rows()返回-1帶來的“陷阱” | 學步園...
  7. layer checkbox
  8. linux服务器运维操作命令,Linux服务器运维常用命令列表
  9. python dataframe 选取字段 特别慢_从parqu读取dask dataframe列重命名速度较慢(er)
  10. php 变量存活期,php 变量生命周期:PHP源码分析-PHP的生_php