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

小さなバグがあるでしょう。;HOST=$2以降

長いオプションの前にダッシュを使用するには追加できます。-ㅏgetopt オプション。

さらに、ホストとアカウントIDには必須オプションがあるため、その後に次のものが必要です。:

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;;

おすすめ記事