getopt、getopts、または手動解析 - 短いオプションと長いオプションの両方をサポートするには何を使用する必要がありますか?

getopt、getopts、または手動解析 - 短いオプションと長いオプションの両方をサポートするには何を使用する必要がありますか?

現在、私は以下の要件を満たすBashスクリプトを書いています。

  • さまざまなUnix / Linuxプラットフォームで実行する必要があります。
  • 短いオプションと(GNU)長いオプションをサポートする必要があります。

私はこれがgetopts移植性の面で好ましい方法であることを知っていますが、私が知っている限り、長いオプションをサポートしていません。

getopt長いオプションはサポートされていますが、バッシュガイド以下について強くお勧めします。

絶対に getopt(1) を使用しないでください。 getoptは空のパラメータ文字列またはスペースを含むパラメータを処理できません。それが存在したことがあることを忘れてください。

したがって、まだ手動解析オプションがあります。これはエラーが発生しやすく、かなり多くの定型句コードを生成し、エラーを直接処理する必要があります(getopt(s)エラー処理を直接実行したい)。

それでは、この場合の最初の選択は何ですか?

ベストアンサー1

getoptvsgetopts宗教的な問題のようです。異議事項getoptについてはバッシュFAQ:

  • getopt空の引数文字列を処理できません」は既知の問題を示すようです。任意に選択できるパラメータはgetoptsまったくサポートされていないようです(少なくともhelp getoptsBash 4.2.24を読むと)。からman getopt

    getopt(3) は、空のオプション引数で長いオプションを解析できます (短いオプションではない)。 getopt(1) は、空のオプションの引数を存在しないかのように扱います。

多くの「伝統的な」実装がgetopt空白を含む引数を解析できないのは事実ですが、util-linuxの実装やBusyboxに含まれる実装の場合はそうではありません。

  • テスト.sh:

    #!/usr/bin/env bash
    getopt -T
    if [ "$?" != 4 ]; then
        echo 2>&1 "Wrong version of 'getopt' detected, exiting..."
        exit 1
    fi
    set -o errexit -o noclobber -o nounset -o pipefail
    params="$(getopt -o ab:c -l alpha,bravo:,charlie --name "$0" -- "$@")"
    eval set -- "$params"
    
    while true
    do
        case "$1" in
            -a|--alpha)
                echo alpha
                shift
                ;;
            -b|--bravo)
                echo "bravo=$2"
                shift 2
                ;;
            -c|--charlie)
                echo charlie
                shift
                ;;
            --)
                shift
                break
                ;;
            *)
                echo "Not implemented: $1" >&2
                exit 1
                ;;
        esac
    done
    
  • ランニング:

    $ ./test.sh -
    $ ./test.sh -acb '   whitespace   FTW   '
    alpha
    charlie
    bravo=   whitespace   FTW   
    $ ./test.sh -ab '' -c
    alpha
    bravo=
    charlie
    $ ./test.sh --alpha --bravo '   whitespace   FTW   ' --charlie
    alpha
    bravo=   whitespace   FTW   
    charlie
    

もちろん、移植性の問題はまだ存在します。そのバージョンが存在しない場合を決定する必要がありますgetoptヤグニーそしてキス指示 - 使用する特定のプラットフォーム用にのみ開発してください。開発時間が無限大に近づくほど、シェルコードの移植性は通常100%に達します。

おすすめ記事