getopt 命令与 getopts 的功能很相似,也是用于解析命令行的选项和参数,使其可以被 Shell 程序简单地解析。不同的是,getopt 命令是 Linux 下的命令行工具,并且 getopt 支持命令行的长选项(比如,--some-option)。另外,在脚本中它们的调用方式也不同。
getopt 的语法类似如下:
getopt [options] [--] optstring parameters
getopt [options] -o|--options optstring [options] [--] parameters
下面是一个示例:
$ getopt f:vl -vl -f/local/filename.conf param_1
-v -l -f /local/filename.conf -- param_1
上例中,“f:vl” 对应 getopt 命令语法中的 optstring(选项字符串),“-vl -f/local/filename.conf param_1” 对应 getopt 命令语法中的 parameters(getopt 命令的参数)。因此,getopt 会按照 optstring 的设置,将 parameters 解析为相应的选项和参数。
所以,“-vl” 被解析为了 “-v” 和 “-l”。与 getopts 类似,因为在选项字符串中 “f” 后有一个冒号(:),所以 “-f/local/filename.conf” 被解析为 “-f /local/filename.conf”。然后解析后的命令行选项和参数之间使用双连字符(--)分隔。
那么我们在 Shell 脚本中怎样使用 getopt 命令来重写我们的命令行参数呢?
实例1
#! /bin/bash
# 将 getopt 解析后的内容设置到位置参数
set -- `getopt f:vl "$@"`
while [ $# -gt 0 ]
do
echo $1
shift
done
此脚本的运行效果如下:
此脚本中的 set 命令语句中,“getopt f:vl "$@"” 表示将传递给脚本的命令行选项和参数作为 getopt 命令的参数,由 getopt 命令解析处理。整个 set 命令语句 “set -- getopt f:vl "$@"
” 则表示将 getopt 命令的输出作为值依次(从左至右)赋值给位置参数(“set -- [args]” 命令会把指定的参数 [args] 依次赋值给位置参数)。
实例2
#! /bin/bash
vflag=off
output=""
filename=""
set -- `getopt hvf:o: "$@"`
function usage() {
echo "USAGE:"
echo " myscript [-h] [-v] [-f <filename>] [-o <filename>]"
exit -1
}
while [ $# -gt 0 ]
do
case "$1" in
-v)
vflag=on
;;
-f)
filename=$2
if [ ! -f $filename ]
then
echo "The source file $filename doesn't exist!"
exit
else
shift
fi
;;
-o)
output=$2
if [ ! -d `dirname $output` ]
then
echo "The output path `dirname $output` doesn't exist!"
exit
else
shift
fi
;;
-h)
usage
exit
;;
--)
shift
break
;;
-*)
echo "Invalid option: $1"
usage
exit 2
;;
*)
break
;;
esac
shift
done
此脚本的运行效果如下:
实例3
我们在前面提到 getopt 还有一个功能是支持长选项(--long-options),下面是一个使用 getopt 处理长选项的实例:
#! /bin/bash
vflag=off
output=""
filename=""
set -- `getopt hvf:o: "$@"`
function usage() {
echo "USAGE:"
echo " myscript [-h] [-v] [-f <filename>] [-o <filename>]"
exit -1
}
while [ $# -gt 0 ]
do
case "$1" in
-v)
vflag=on
;;
-f)
filename=$2
if [ ! -f $filename ]
then
echo "The source file $filename doesn't exist!"
exit
else
shift
fi
;;
-o)
output=$2
if [ ! -d `dirname $output` ]
then
echo "The output path `dirname $output` doesn't exist!"
exit
else
shift
fi
;;
-h)
usage
exit
;;
--)
shift
break
;;
-*)
echo "Invalid option: $1"
usage
exit 2
;;
*)
break
;;
esac
shift
done
上述脚本中的 “getopt -o a::bc: --long arga::,argb,argc: -n 'getopt_longopt.sh' -- "$@"” 一行脚本中,getopt 命令的 “-o” 选项表示告诉 getopt 识别哪些短(一个字符)的选项。getopt 命令的 “--long” (或 -l) 选项表示告诉 getopt 识别哪些长选项。getopt 命令的 “-n” 选项告诉 getopt(3) 程序在报告错误时使用什么文件名(或程序名)。
getopt 命令的 “-o” 选项所指定的选项字符串遵循如下规则:
- 每一个字符代表一个选项;
- 字符后跟一个冒号(:)表示选项需要一个参数;
- 字符后跟两个冒号(::)表示选项有个可选参数。
本文参考自 《Linux Shell命令行及脚本编程实例详解 》