解析命令行选项
Contents
1. 概述
作为 Linux 用户,我们经常使用各种命令行实用程序和脚本。开发脚本时的常见任务之一是解析命令行选项。这些选项可以很短也可以很长。
在本教程中,我们将使用bash 的getopts 函数和*getopt 实用程序来解析命令行选项。*
2. 使用getopts解析简短的命令行选项
在 Bash中,我们可以使用短命令行选项和长命令行选项。短选项以单个*连字符 (-)字符开头,后跟单个字母数字字符,而长选项以双连字符 (-)*字符开头,后跟多个字符。
我们可以指示*ls *命令显示隐藏文件:
$ ls -a
. .. hello.txt
$ ls --all
. .. hello.txt
在上面的例子中:
- -a 代表空头选项
- –all 代表长选项
**要解析简短的命令行选项,我们可以使用bash的内置函数getopts。**它将位置参数解析为选项。
2.1. getopts语法
getopts函数的语法是:
getopts optstring opt [arg ...]
在上述函数中:
- optstring表示支持的选项。如果后面有一个冒号 (:) ,则该选项需要一个参数。例如,如果选项c需要一个参数,那么它将在optstring中表示为c:
- 当选项具有关联的参数时,getopts会将参数作为字符串存储在OPTARG shell 变量中。例如,传递给选项c 的参数将存储在OPTARG变量中。
- opt包含已解析的选项。
在接下来的部分中,当我们看到它们在行动中时,这些概念将变得清晰。
2.2. 脚本中的示例用法
让我们创建一个简单的 shell 脚本来看看它的用法:
#!/bin/bash
while getopts 'abc:h' opt; do
case "$opt" in
a)
echo "Processing option 'a'"
;;
b)
echo "Processing option 'b'"
;;
c)
arg="$OPTARG"
echo "Processing option 'c' with '${OPTARG}' argument"
;;
?|h)
echo "Usage: $(basename $0) [-a] [-b] [-c arg]"
exit 1
;;
esac
done
shift "$(($OPTIND -1))"
让我们执行脚本并观察输出:
$ chmod +x parse-command-line-args.sh
$ ./parse-command-line-args.sh -a
Processing option 'a'
$ ./parse-command-line-args.sh -c test-value
Processing option 'c' with 'test-value' argument
$ ./parse-command-line-args.sh -ab
Processing option 'a'
Processing option 'b'
2.3. getopts中的错误报告
getopts函数在两种情况下报告错误——首先,使用无效选项时,其次,未提供参数时:
- 如果提供了无效选项,则opt变量包含问号*(?)字符*
- 如果未提供必需的参数,则opt变量包含冒号*(:)字符*
我们可以捕获这两种错误场景并向用户显示适当的错误消息。让我们修改脚本来处理这些场景:
#!/bin/bash
while getopts ':abc:h' opt; do
case "$opt" in
a)
echo "Processing option 'a'"
;;
b)
echo "Processing option 'b'"
;;
c)
arg="$OPTARG"
echo "Processing option 'c' with '${OPTARG}' argument"
;;
h)
echo "Usage: $(basename $0) [-a] [-b] [-c arg]"
exit 0
;;
:)
echo -e "option requires an argument.\nUsage: $(basename $0) [-a] [-b] [-c arg]"
exit 1
;;
?)
echo -e "Invalid command option.\nUsage: $(basename $0) [-a] [-b] [-c arg]"
exit 1
;;
esac
done
shift "$(($OPTIND -1))"
现在,我们将执行脚本并检查错误消息:
$ ./parse-command-line-args.sh -c
option requires an argument.
Usage: parse-command-line-args.sh [-a] [-b] [-c arg]
$ ./parse-command-line-args.sh -e
Invalid command option.
Usage: parse-command-line-args.sh [-a] [-b] [-c arg]
**请注意,我们也更新了optstring 。现在它以冒号 (:)字符开头,它禁止默认错误消息。**除此之外,我们可以使用OPTERR环境变量来改变错误报告行为。当OPTERR变量设置为零时, getopts函数禁用错误报告。
3. 使用getopt解析长命令行选项
有时,使用长命令行选项来提高可读性很方便。但是,getopts仅支持简短的命令行选项。我们可以使用 GNU 的getopt命令来解析长的命令行选项:
#!/bin/bash
VALID_ARGS=$(getopt -o abg:d: --long alpha,beta,gamma:,delta: -- "$@")
if [[ $? -ne 0 ]]; then
exit 1;
fi
eval set -- "$VALID_ARGS"
while [ : ]; do
case "$1" in
-a | --alpha)
echo "Processing 'alpha' option"
shift
;;
-b | --beta)
echo "Processing 'beta' option"
shift
;;
-g | --gamma)
echo "Processing 'gamma' option. Input argument is '$2'"
shift 2
;;
-d | --delta)
echo "Processing 'delta' option. Input argument is '$2'"
shift 2
;;
--) shift;
break
;;
esac
done
在上面的脚本中:
- -o选项代表简短的命令行选项
- –long选项代表长的命令行选项
让我们执行脚本并观察输出:
$ chmod +x parse-long-command-line-args.sh
$ ./parse-long-command-line-args.sh -a
Processing 'alpha' option
$ ./parse-long-command-line-args.sh --alpha
Processing 'alpha' option
$ ./parse-long-command-line-args.sh --delta test-value
Processing 'delta' option. Input argument is 'test-value'
$ ./parse-long-command-line-args.sh -g test-value
Processing 'gamma' option. Input argument is 'test-value'