getopt
とgetopts
は異なる獣であり、人々は彼らが何をしているのかについて少し誤解しているようです. ループ内でコマンドライン オプションを処理し、見つかった各オプションと値を順番に組み込み変数に割り当てるため getopts
の組み込みコマンドです。これにより、それらをさらに処理できます。ただし、 は外部ユーティリティ プログラムであり、実際にはbash 、Perlモジュール、または Python /モジュールのようにオプションを処理しません。渡されたオプションを正規化するだけです。つまり、より標準的な形式に変換して、シェル スクリプトで処理しやすくします。たとえば、 を適用すると、次のように変換される場合があります。bash
getopt
getopts
Getopt
optparse
argparse
getopt
getopt
myscript -ab infile.txt -ooutfile.txt
これに:
myscript -a -b -o outfile.txt infile.txt
実際の処理は自分で行う必要があります。getopt
オプションを指定できる方法にさまざまな制限を加える場合は、まったく使用する必要はありません。
- 引数ごとに 1 つのオプションのみを配置します。
- すべてのオプションは、位置パラメータ (つまり、オプションではない引数) の前に置かれます。
- 値を持つオプション (
-o
上記など) の場合、値は (スペースの後に) 別の引数として指定する必要があります。
getopt
の代わりにgetopts
使用する理由 基本的な理由は、getopt
長い名前のコマンドライン オプションをサポートしているのは GNU だけだからです。1 (GNUgetopt
は Linux のデフォルトです。Mac OS X と FreeBSD には基本的であまり役に立たない が付属していますgetopt
が、GNU バージョンをインストールできます。以下を参照してください。)
たとえば、GNU を使用する例を次に示しgetopt
ます。私のスクリプトは次のjavawrap
とおりです。
# NOTE: This requires GNU getopt. On Mac OS X and FreeBSD, you have to install this
# separately; see below.
TEMP=$(getopt -o vdm: --long verbose,debug,memory:,debugfile:,minheap:,maxheap: \
-n 'javawrap' -- "$@")
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
# Note the quotes around '$TEMP': they are essential!
eval set -- "$TEMP"
VERBOSE=false
DEBUG=false
MEMORY=
DEBUGFILE=
JAVA_MISC_OPT=
while true; do
case "$1" in
-v | --verbose ) VERBOSE=true; shift ;;
-d | --debug ) DEBUG=true; shift ;;
-m | --memory ) MEMORY="$2"; shift 2 ;;
--debugfile ) DEBUGFILE="$2"; shift 2 ;;
--minheap )
JAVA_MISC_OPT="$JAVA_MISC_OPT -XX:MinHeapFreeRatio=$2"; shift 2 ;;
--maxheap )
JAVA_MISC_OPT="$JAVA_MISC_OPT -XX:MaxHeapFreeRatio=$2"; shift 2 ;;
-- ) shift; break ;;
* ) break ;;
esac
done
これにより--verbose -dm4096 --minh=20 --maxhe 40 --debugfi="/Users/John Johnson/debug.txt"
、同様のオプションを指定できます。への呼び出しの効果は、より簡単に処理できるようにgetopt
、へのオプションを正規化することです。スペースを含む引数が適切に処理されるようにするため、and--verbose -d -m 4096 --minheap 20 --maxheap 40 --debugfile "/Users/John Johnson/debug.txt"
を引用することは重要です。"$1"
"$2"
最初の 9 行 (その行までのすべて) を削除してもeval set
、コードは機能します。しかし、あなたのコードは、どんな種類のオプションを受け入れるかという点で、よりうるさいものになります: 特に、上記の「標準的な」形式ですべてのオプションを指定する必要があります。ただし、 を使用するとgetopt
、1 文字のオプションをグループ化したり、長いオプションのあいまいでない短い形式を使用したり、--file foo.txt
または--file=foo.txt
スタイルを使用したり、-m 4096
またはスタイルを使用したり-m4096
、オプションと非オプションを任意の順序で組み合わせ たりすることができます。getopt
認識できないオプションやあいまいなオプションが見つかった場合も、エラー メッセージが出力されます。
注: 実際には、basicと GNUの 2 つのまったく異なるバージョンがあり、機能と呼び出し規約が異なります。2 Basicはかなり壊れています。長いオプションを処理できないだけでなく、引数や空の引数の中に埋め込まれたスペースを処理することさえできません。上記のコードは、basic では機能しません。GNUは Linux ではデフォルトでインストールされますが、Mac OS X および FreeBSD では個別にインストールする必要があります。Mac OS X では、MacPorts ( http://www.macports.org )をインストールしてから、GNU を(通常は に)インストールします。getopt
getopt
getopt
getopt
getopts
getopt
getopt
sudo port install getopt
getopt
/opt/local/bin
/opt/local/bin
/usr/bin
. FreeBSD では、 をインストールしmisc/getopt
ます。
独自のプログラムのサンプル コードを変更するためのクイック ガイド: 最初の数行のうち、getopt
. の後にプログラム名を変更し、 の後-n
に短いオプションを指定し、 の後-o
に長いオプションを指定する必要があります--long
。値を取るオプションの後にはコロンを付けます。
set
最後に、代わりにだけが含まれているコードがあればeval set
、それは BSD 用に書かれていgetopt
ます。eval set
の両方のバージョンで正常に動作するスタイルを使用するように変更する必要がありますがgetopt
、プレーンset
は GNU では正しく動作しませんgetopt
。
1実際、getopts
inksh93
は長い名前のオプションをサポートしていますが、このシェルは ほど頻繁には使用されませんbash
。ではzsh
、 を使用zparseopts
してこの機能を取得します。
2技術的には、「GNU getopt
」は誤称です。このバージョンは、実際には GNU プロジェクトではなく Linux 用に作成されました。ただし、すべての GNU 規則に従い、"GNU getopt
" という用語が一般的に使用されます (たとえば、FreeBSD では)。