使用 getopt 处理命令行长参数(长选项)

getopt命令并不是bash的内建命令,它是由util-linux包提供的外部命令。


getopt 与 getopts 的区别

  • getopts 是 shell 内建命令, getopt 是一个独立外部工具
  • getopts 使用语法简单,getopt 使用语法复杂
  • getopts 不支持长参数(长选项,如 --option), getopt 支持
  • getopts 不会重排所有参数的顺序,getopt会重排参数顺序 (getopts 的 shell 内置 OPTARG 这个变量,getopts 通过修改这个变量依次获取参数,而 getopt 必须使用 set 来重新设定位置参数,然后在 getopt 中使用 shift 来依次获取参数)
  • 如果某个参数中含有空格,那么这个参数就变成了多个参数。因此,基本上,如果参数中可能含有空格,那么必须用getopts(新版本的 getopt 也可以使用空格的参数,只是传参时,需要用 双引号 包起来)。
getopt 命令选项说明:
getopt 命令的选项说明:
-a 使getopt长选项支持"-"符号打头,必须与-l同时使用
-l 后面接getopt支持长选项列表
-n program如果getopt处理参数返回错误,会指出是谁处理的这个错误,这个在调用多个脚本时,很有用
-o 后面接短参数选项,这种用法与getopts类似,
-u 不给参数列表加引号,默认是加引号的(不使用-u选项),例如在加不引号的时候 --longopt "select * from db1.table1" $2只会取到select ,而不是完整的SQL语句。

选项的使用定义规则类似 getopts :
例如
ab:c::

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

示例:
#!/bin/bash

#定义选项, -o 表示短选项 -a 表示支持长选项的简单模式(以 - 开头) -l 表示长选项 
# a 后没有冒号,表示没有参数
# b 后跟一个冒号,表示有一个必要参数
# c 后跟两个冒号,表示有一个可选参数(可选参数必须紧贴选项)
# -n 出错时的信息
# -- 也是一个选项,比如 要创建一个名字为 -f 的目录,会使用 mkdir -- -f ,
#    在这里用做表示最后一个选项(用以判定 while 的结束)
# $@ 从命令行取出参数列表(不能用用 $* 代替,因为 $* 将所有的参数解释成一个字符串
#                         而 $@ 是一个参数数组)
    
TEMP=`getopt -o ab:c:: -a -l apple,banana:,cherry:: -n "test.sh" -- "$@"`

# 判定 getopt 的执行时候有错,错误信息输出到 STDERR
if [ $? != 0 ]
then
	echo "Terminating....." >&2
	exit 1
fi

# 重新排列参数的顺序
# 使用eval 的目的是为了防止参数中有shell命令,被错误的扩展。
eval set -- "$TEMP"

# 处理具体的选项
while true
do
	case "$1" in
		-a | --apple | -apple)
			echo "option a"
			shift
			;;
		-b | --banana | -banana)
			echo "option b, argument $2"
			shift 2
			;;
		-c | --cherry | -cherry)
			case "$2" in
				"") # 选项 c 带一个可选参数,如果没有指定就为空
					echo "option c, no argument"
					shift 2
					;;
				*)
					echo "option c, argument $2"
					shift 2
			esac
			;;
		--)
			shift
			break
			;;
		*) 
			echo "Internal error!"
			exit 1
			;;
		esac

done

#显示除选项外的参数(不包含选项的参数都会排到最后)
# arg 是 getopt 内置的变量 , 里面的值,就是处理过之后的 $@(命令行传入的参数)
for arg do
   echo '--> '"$arg" ;
done


你可能感兴趣的:(使用 getopt 处理命令行长参数(长选项))