3种在 shell 脚本中处理选项的方法。
1. 处理简单选项
先前的 shiftparams.sh 脚本中介绍过如何使用 shift 命令来依次处理脚本的命令行参数。你
也可以用同样的方法来处理命令行选项。
在提取单个参数时,使用 "case" 语句来判断某个参数是否为选项:
- $ cat extractoptions.sh
- #!/bin/bash
- # Extract command-line options
- #
- echo
- while [ -n "$1" ]
- do
- case "$1" in
- -a) echo "Found the -a option" ;;
- -b) echo "Found the -b option" ;;
- -c) echo "Found the -c option" ;;
- *) echo "$1 is not an option" ;;
- esac
- shift
- done
- echo
- exit
- $
- $ ./extractoptions.sh -a -b -c -d
- Found the -a option
- Found the -b option
- Found the -c option
- -d is not an option
- $
"case" 语句会检查每个参数,确认是否为有效的选项。找到一个,处理一个。无论选项在命令行中以何种顺序出现,这种方法都能应对。
2.分离参数和选项
经常碰到需要同时使用选项和参数的情况。在 Linux 中,处理这个问题的标准做法是使用特殊字符将两者分开,该字符会告诉脚本选项何时结束,普通参数何时开始。
Linux 中,这个特殊字符是双连字符(--)。shell 会用双连字符表明选项部分结束。在双连字符之后,脚本就可以放心地将剩下的部分作为参数处理了。
要检查双连字符,只需在 "case" 语句中加一项即可:
- $ cat extractoptionsparams.sh
- #!/bin/bash
- # Extract command-line options and parameters
- #
- echo
- while [ -n "$1" ]
- do
- case "$1" in
- -a) echo "Found the -a option" ;;
- -b) echo "Found the -b option" ;;
- -c) echo "Found the -c option" ;;
- --) shift
- break;;
- *) echo "$1 is not an option" ;;
- esac
- shift
- done
- #
- echo
- count=1
- for param in $@
- do
- echo "Parameter #$count: $param"
- count=$[ $count + 1 ]
- done
- echo
- exit
- $
- $ ./extractoptionsparams.sh -a -b -c test1 test2 test3
- Found the -a option
- Found the -b option
- Found the -c option
- test1 is not an option
- test2 is not an option
- test3 is not an option
- $
进行同样的测试,只是这次会用双连字符将命令行中的选项和参数分开:
- $ ./extractoptionsparams.sh -a -b -c -- test1 test2 test3
- Found the -a option
- Found the -b option
- Found the -c option
- Parameter #1: test1
- Parameter #2: test2
- Parameter #3: test3
- $
3. 处理含值的选项
(1)有些选项需要一个额外的参数值。在这种情况下,命令行看起来像下面这样:
$ ./testing.sh -a test1 -b -c -d test2
(2)当命令行选项要求额外的参数时,脚本必须能够检测到并正确地加以处理。
来看下面的处理方法:
- $ cat extractoptionsvalues.sh
- #!/bin/bash
- # Extract command-line options and values
- #
- echo
- 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
- #
- echo
- count=1
- for param in $@
- do
- echo "Parameter #$count: $param"
- count=$[ $count + 1 ]
- done
- exit
- $
- $ ./extractoptionsvalues.sh -a -b BValue -d
- Found the -a option
- Found the -b option with parameter value BValue
- -d is not an option
- $
在这个例子中,"case" 语句定义了 3 个要处理的选项。-b 选项还需要一个额外的参数值。
由于要处理的选项位于$1,因此额外的参数值就应该位于$2(因为所有的参数在处理完之后都会被移出)。
只要将参数值从$2 变量中提取出来就可以了。当然,因为这个选项占用了两个位置,所以还需要使用 shift 命令多移动一次。
只需这些基本的功能,整个过程就能正常工作,不管按什么顺序放置选项(只要记住放置好相应的选项参数):
- $ ./extractoptionsvalues.sh -c -d -b BValue -a
- Found the -c option
- -d is not an option
- Found the -b option with parameter value BValue
- Found the -a option
- $
现在 shell 脚本已经拥有了处理命令行选项的基本能力,但还有一些局限。例如,当你想合并多个选项时,脚本就不管用了:
- $ ./extractoptionsvalues.sh -ac
- -ac is not an option
- $