如何使用 getopt 将长样式命令行选项传递给 bash 脚本?

如何使用 getopt 将长样式命令行选项传递给 bash 脚本?

我有一个脚本,是我从谷歌搜索中收集到的一些知识拼凑而成的:

#!/usr/bin/env bash

usage() {
    declare -r script_name=$(basename "$0")
    echo """
Usage:
"${script_name}" [option] <name>

Option:
    -host <foo.com|bar.com|baz.com|...>
    -accountId <001123456789|002123456789|...>
"""
}

main() {
    if [[ $# -eq 0 ]]; then
        usage
        exit 1
    fi

OPTIONS=$(getopt -o '' -l help,host,accountId -- "$@")

eval set -- "$OPTIONS"

while true
do
    case $1 in
    -help) usage
           exit 0
           ;;
    -accountId) ACCOUNTID=$2; shift 2;;
    -host) HOST=$2 shift 2;;
    --) shift ; break ;;
    esac
done

echo host: $HOST, accountId: $ACCOUNTID

}

main "$@"

这是它的输出:

$ . test.sh -help
host: , accountId:

$ . test.sh -host foo.com -accountId 001123456789
host: , accountId:

我做错了什么?

答案1

小bug,应该有;HOST=$2 之后

如果你想在长选项前面使用一个破折号,你可以添加-Agetopt 选项。

此外,由于 host 和 accountId 有必需的选项,因此它们后面应该跟一个:

OPTIONS=$( getopt -a -o '' -l help,host:,accountId: -- "$@" )

(camelCase 不是最好的选项,不如只使用 accountid 而不是 accountId)

我通常更喜欢同时提供长期和短期选项,因此会使用:

OPTIONS=$( getopt -a -o 'h:a:' -l help,host:,accountId: -- "$@" )

-a|--accountId) ACCOUNTID=$2; shift 2;;
-h|--host) HOST=$2; shift 2;;

您还应该检查 getopt 的结果代码,如果选项错误,您就不想继续:

因此,在 OPTIONS=$(... 行之后添加以下内容:

if [[ $? -ne 0 ]] ; then
    usage ; exit 1
fi

顺便说一句,如果正在显示用法,您可能总是想退出,所以为什么不把1号出口在使用结束时,您可以使用:

[[ $# -eq 0 ]] && usage
...
[[ $? -ne 0 ]] && usage
...
--help) usage;;

相关内容