Linux——处理选项

1. 处理简单选项

在提取每个单独参数时,用case语句来判断某个参数是否为选项

#!/bin/bash
# extracting command line options as parameters

while [[ -n "$1" ]]; do
	case "$1" in
		-a) echo "Found the -a option";;
		-b) echo "Found the -b option";;
		-c) echo "Fount the -c option";;
		 *) echo "$1 is not an option";;
	esac
	shift
done
$ ./test.sh -a -b -c -d
Found the -a option
Found the -b option
Fount the -c option
-d is not an option

case语句检查每个参数是不是有效选项。如果是的话,就运行对应case语句中命令。不管悬系那个按什么顺序出现在命令行上,这种方法都适用。

case语句在命令行参数中找到一个选项,就处理一个选项。如果命令行上还提供了其他参数,可以在case语句的通用情况处理部分中处理。

2. 分离参数和选项

对于同时使用选项和参数的情况。Linux采用双破折线(–)将二者分开。

#!/bin/bash
# extracting command line options and parameters

while [[ -n "$1" ]]; do
	case "$1" in
		-a) echo "Found the -a option";;
		-b) echo "Found the -b option";;
		-c) echo "Fount the -c option";;
		--) shift 
			break;;
		 *) echo "$1 is not an option";;
	esac
	shift
done

count=1
for param in $@
do
	echo "Parameter #$count: $param"
	count=$[ $count + 1 ]
done
$ ./test.sh -c -a -b -- test1 test2 test3
Fount the -c option
Found the -a option
Found the -b option
Parameter #1: test1
Parameter #2: test2
Parameter #3: test3

当脚本遇到双破折线时,它会停止处理选项,并将剩下的参数都当作命令行参数。

3. 处理带值的选项

有些选项会带上一个额外的参数值,类似:./testing.sh -a test1 -b -c -d test2

#!/bin/bash
# extracting command line options and values

while [[ -n "$1" ]]; do
	case "$1" in
		-a) echo "Found the -a option";;
		-b) param="$2"
			echo "Found the -b option, with parameter value $param"
			shift;;
		-c) echo "Found the -c option";;
		--) shift
			break;;
		 *) echo "$1 is not an option";;
	esac
	shift
done

count=1
for param in $@
do
	echo "Parameter #$count: $param"
	count=$[ $count + 1 ]
done
$ ./test.sh -a -b test1 -d
Found the -a option
Found the -b option, with parameter value test1
-d is not an option

在这个例子中,case语句定义了三个它要处理的选项。-b选项还需要一个额外的参数值。 由于要处理的参数是$1,额外的参数值就应该位于$2(因为所有的参数在处理完之后都会被移出)。只要将参数值从$2变量中提取出来就可以了。当然,因为这个选项占用了两个参数位,所 以你还需要使用shift命令多移动一个位置。

使用getopt命令

getopt命令是一个在处理命令行选项和参数时非常方便的工具。它能够识别命令行参数, 从而在脚本中解析它们时更方便。

1. 命令格式:
getopt opstring parameters

optstring定义了命令行有效的选项字母,还定义了哪些选项字母需要参数值。
首先,在optstring中列出你要在脚本中用到的每个命令行选项字母。然后,在每个需要参数值的选项字母后加一个冒号。getopt命令会基于你定义的optstring解析提供的参数。

示例:

扫描二维码关注公众号,回复: 13204205 查看本文章
$ getopt ab:cd -a -b test1 -cd test2 test3
 -a -b test1 -c -d -- teset2 test3
 $

optstring定义了四个有效选项字母:a、b、c和d。冒号(:)被放在了字母b后面,因为b选项需要一个参数值。当getopt命令运行时,它会检查提供的参数列表(-a -b test1 -cd test2 test3),并基于提供的optstring进行解析。注意,它会自动将-cd选项分成两个单独的选项,并插入双破折线来分隔行中的额外参数。

2. 在脚本中使用getopt
方法是用getopt命令生成的格式化后的版本来替换已有的命令行选项和参数。用set命令能够做到。
set命令的选项之一是双破折线(–),它会将命令行参数替换成set命令的命令行值。 然后,该方法会将原始脚本的命令行参数传给getopt命令,之后再将getopt命令的输出传给set命令,用getopt格式化后的命令行参数来替换原始的命令行参数,看起来如下所示:

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

现在原始的命令行参数变量的值会被getopt命令的输出替换,而getopt已经为我们格式化 好了命令行参数

#!/bin/bash
# extracting command line options and values with getopt

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

while [[ -n "$1" ]]; do
	case "$1" in
		-a) echo "Found the -a option";;
		-b) param="$2"
			echo "Found the -b option, with parameter value $param"
			shift;;
		-c) echo "Found the -c option";;
		--) shift
			break;;
		 *) echo "$1 is not an option";;
	esac
	shift
done

count=1
for param in $@
do
	echo "Parameter #$count: $param"
	count=$[ $count + 1 ]
done
$ ./test.sh -ac
Found the -a option
Found the -c option
$ ./test.sh -a -b test1 -cd test2 test3 test4
Found the -a option
Found the -b option, with parameter value test1
Found the -c option
-d is not an option
Parameter #1: test2
Parameter #2: test3
Parameter #3: test4

使用getopts

如果参数值带有空格和引号,使用getpot命令会出现问题:

$ ./test.sh -a -b test1 -cd "test2 test3" test4

Found the -a option
Found the -b option, with parameter value test1
Found the -c option
-d is not an option
Parameter #1: test2
Parameter #2: test3
Parameter #3: test4
它会将空格当作参数分隔符,而不是根 据双引号将二者当作一个参数。

与getopt不同,前者将命令行上选项和参数处理后只生成一个输出,而getopts命令能够 和已有的shell参数变量配合默契。
每次调用它时,它一次只处理命令行上检测到的一个参数。处理完所有的参数后,它会退出并返回一个大于0的退出状态码。这让它非常适合用解析命令行所有参数的循环中。

格式:
getopts optstring variable

optstring值类似于getopt命令中的那个。有效的选项字母都会列在optstring中,如果选项字母要求有个参数值,就加一个冒号。要去掉错误消息的话,可以在optstring之前加一个 冒号。getopts命令将当前参数保存在命令行中定义的variable中。
getopts命令会用到两个环境变量。如果选项需要跟一个参数值,OPTARG环境变量就会保 存这个值。OPTIND环境变量保存了参数列表中getopts正在处理的参数位置。这样你就能在处 理完选项之后继续处理其他命令行参数了。

#!/bin/bash
# simple demonstration of the getopts command

while getopts :ab:c opt; do
	case "$opt" in
		a) echo "Found the -a option";;
		b) echo "Found the -b option, with value $OPTARG";;
		c) echo "Found the -c option";;
		*) echo "Unknown option: $opt";;
	esac
done
$ ./getopts.sh -b "test1 test2" -a
Found the -b option, with value test1 test2
Found the -a option

在本例中case语句的用法有些不同。getopts命令解析命令行选项时会移除开头的单破折线,所以在case定义中不用单破折线。

$ ./getopts.sh -abtest1
Found the -a option
Found the -b option, with value test1

将选项字母和参数值放在一起使用,而不用加空格

optstring中未定义的选项字母会以问号形式发送给代码。 getopts命令知道何时停止处理选项,并将参数留给你处理。在getopts处理每个选项时,
它会将OPTIND环境变量值增一。在getopts完成处理时,你可以使用shift命令和OPTIND值来 移动参数

#!/bin/bash
# simple demonstration of the getopts command

while getopts :ab:cd opt; do
	case "$opt" in
		a) echo "Found the -a option";;
		b) echo "Found the -b option, with value $OPTARG";;
		c) echo "Found the -c option";;
		d) echo "Found the -d option";;
		*) echo "Unknown option: $opt";;
	esac
done

shift $[ $OPTIND - 1]

echo
count=1
for param in "$@"
do
	echo "Parameter $count: $param"
	count=$[ $count + 1 ]
done
$ ./getopts.sh -a -b test1 -d test2 test3 test4

Found the -a option
Found the -b option, with value test1
Found the -d option

Parameter 1: test2
Parameter 2: test3
Parameter 3: test4

选项标准化

选项 描述
-a 显示所有对象
-c 生成一个计数
-d 指定一个目录
-d 扩展一个对象
-f 指定读入数据的文件
-h 显示命令的帮助信息
-i 忽略文本大小写
-l 产生输出的长格式文本
-n 使用非交互模式(批处理)
-o 将所有输出重定向到指定的输出文件
-q 以安静模式运行
-r 递归处理目录和文件
-s 以安静模式运行
-v 生成详细输出
-x 排除某个对象
-y 对所有问题回答yes

猜你喜欢

转载自blog.csdn.net/cold___play/article/details/121083274