Content #
- 命令格式
getopt命令可以接受一系列任意形式的命令行选项和参数,并自动将其转换成适当的格式。getopt的命令格式如下:
getopt optstring parameters
optstring是这个过程的关键所在。它定义了有效的命令行选项字母,还定义了哪些选项字母需要参数值。
首先,在optstring中列出要在脚本中用到的每个命令行选项字母。然后,在每个需要参数值的选项字母后面加一个冒号。getopt命令会基于你定义的 optstring解析提供的参数。
$ getopt ab:cd -a -b BValue -cd test1 test2
-a -b BValue -c -d -- test1 test2
optstring定义了4个有效选项字母:a、b、c和d。冒号(:)被放在了字母b后面,因为b选项需要一个参数值。当getopt命令运行时,会检查参数列表(-a -b BValue -cd test1 test2),并基于提供的optstring进行解析。注意,它会自动将-cd分成两个单独的选项,并插入双连字符来分隔命令行中额外的参数。
如果optstring未包含你指定的选项,则在默认情况下,getopt命令会产生一条错误消息:
$ getopt ab:cd -a -b BValue -cde test1 test2
getopt: invalid option -- 'e'
-a -b BValue -c -d -- test1 test2
如果想忽略这条错误消息,可以使用getopt的-q选项:
$ getopt -q ab:cd -a -b BValue -cde test1 test2
-a -b 'BValue' -c -d -- 'test1' 'test2'
注意,getopt命令选项必须出现在optstring之前。
- 在脚本中使用getopt
难点在于要使用getopt命令生成的格式化版本替换已有的命令行选项和参数。这得求助于set命令。
set命令有一个选项是双连字符(–),可以将位置变量的值替换成set命令所指定的值。
具体做法是将脚本的命令行参数传给getopt命令,然后再将getopt命令的输出传给set命令,用getopt格式化后的命令行参数来替换原始的命令行参数:
set -- $(getopt -q ab:cd "$@")
现在,位置变量原先的值会被getopt命令的输出替换掉,后者已经为我们格式化好了命令行参数。
利用这种方法,就可以写出处理命令行参数的脚本了:
$ cat extractwithgetopt.sh
#!/bin/bash
# Extract command-line options and values with getopt
#
set -- $(getopt -q ab:cd "$@")
#
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
$
如果运行带有复杂选项的脚本,就可以看出效果了: $ ./extractwithgetopt.sh -ac
Found the -a option Found the -c option $ 当然,正常的功能也照样没有问题: $ ./extractwithgetopt.sh -c -d -b BValue -a test1 test2
Found the -c option -d is not an option Found the -b option with parameter value ‘BValue’ Found the -a option
Parameter #1: ’test1' Parameter #2: ’test2' $
目前看起来相当不错。但是,getopt命令中仍然隐藏着一个小问题。看看这个例子: $ ./extractwithgetopt.sh -c -d -b BValue -a “test1 test2” test3
Found the -c option -d is not an option Found the -b option with parameter value ‘BValue’ Found the -a option
Parameter #1: ’test1 Parameter #2: test2' Parameter #3: ’test3' $ getopt命令并不擅长处理带空格和引号的参数值。它会将空格当作参数分隔符,而不是根据双引号将二者当作一个参数。这就需要用getopts来解决了。
From #
Linux命令行与shell脚本编程大全