現在、私は以下の要件を満たすBashスクリプトを書いています。
- さまざまなUnix / Linuxプラットフォームで実行する必要があります。
- 短いオプションと(GNU)長いオプションをサポートする必要があります。
私はこれがgetopts
移植性の面で好ましい方法であることを知っていますが、私が知っている限り、長いオプションをサポートしていません。
getopt
長いオプションはサポートされていますが、バッシュガイド以下について強くお勧めします。
絶対に getopt(1) を使用しないでください。 getoptは空のパラメータ文字列またはスペースを含むパラメータを処理できません。それが存在したことがあることを忘れてください。
したがって、まだ手動解析オプションがあります。これはエラーが発生しやすく、かなり多くの定型句コードを生成し、エラーを直接処理する必要があります(getopt(s)
エラー処理を直接実行したい)。
それでは、この場合の最初の選択は何ですか?
ベストアンサー1
getopt
vsgetopts
宗教的な問題のようです。異議事項getopt
についてはバッシュFAQ:
「
getopt
空の引数文字列を処理できません」は既知の問題を示すようです。任意に選択できるパラメータはgetopts
まったくサポートされていないようです(少なくともhelp getopts
Bash 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%に達します。