getopt
とgetopts
は別の獣であり、人々は彼らが何をするかについて少し誤解しているようです。 getopts
は、bash
コマンドラインオプションをループで処理し、見つかった各オプションと値を組み込み変数に順に割り当てる組み込みコマンドです。これにより、さらに処理することができます。 getopt
ただし、は外部ユーティリティプログラムであり、実際には、たとえばbash getopts
、Perl Getopt
モジュール、Python optparse
/ argparse
モジュールのようにオプションを処理しません。そのすべてgetopt
すなわち、それはそれらを処理するシェルスクリプトのために簡単だそうことを、より標準的な形式に変換-んは、渡されたオプションは、正規化しています。たとえば、アプリケーションはgetopt
次のものを変換する場合があります。
myscript -ab infile.txt -ooutfile.txt
これに:
myscript -a -b -o outfile.txt infile.txt
実際の処理は自分で行う必要があります。getopt
オプションの指定方法にさまざまな制限を加える場合は、まったく使用する必要はありません。
- 引数ごとに1つのオプションのみを配置します。
- すべてのオプションは、位置パラメータ(つまり、非オプション引数)の前に配置されます。
- 値を持つオプション(
-o
上記など)の場合、値は(スペースの後の)個別の引数として渡す必要があります。
getopt
代わりになぜ使用するのgetopts
ですか?基本的な理由は、GNUだけgetopt
が長い名前のコマンドラインオプションをサポートしていることです。1(getopt
Linuxでは、GNU がデフォルトです。MacOS XおよびFreeBSDには、基本的であまり役に立たないが付属していますgetopt
が、GNUバージョンをインストールできます。以下を参照してください。)
たとえば、次のgetopt
名前の私のスクリプトからのGNUの使用例は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
オプションを正規化して、--verbose -d -m 4096 --minheap 20 --maxheap 40 --debugfile "/Users/John Johnson/debug.txt"
より簡単に処理できるようにすることです。前後の引用符は"$1"
、"$2"
スペースを含む引数が適切に処理されるようにするために重要です。
最初の9行(行全体)を削除してもeval set
、コードは機能します!ただし、コードでは、どのような種類のオプションが受け入れられるかが非常に厳しくなります。特に、上記の「正規」の形式ですべてのオプションを指定する必要があります。getopt
ただし、を使用すると、1文字のオプションをグループ化し--file foo.txt
たり、長いオプションのより明確な形式を使用したり、or --file=foo.txt
スタイルを使用したり、or スタイルを使用し-m 4096
たり-m4096
、オプションと非オプションを任意の順序で組み合わせたりすることができます。 getopt
また、認識されないオプションやあいまいなオプションが見つかった場合にもエラーメッセージを出力します。
注:実際には、基本とGNUの2つの完全に異なるバージョンがありgetopt
、異なる機能と異なる呼び出し規約があります。2 Basic はかなり壊れています:長いオプションを処理しないだけでなく、引数または空の引数内の埋め込みスペースも処理できませんが、これは正しく行われます。上記のコードは基本的に動作しません。LinuxにはデフォルトでGNU がインストールされていますが、Mac OS XとFreeBSDでは個別にインストールする必要があります。Mac OS Xでは、MacPorts(http://www.macports.org)をインストールしてから、GNU (通常はに)をインストールし、それがシェルパスの先にあることを確認します。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
、ksh93
は長い名前のオプションをサポートしていますが、このシェルはほど頻繁には使用されませんbash
。ではzsh
、を使用zparseopts
してこの機能を取得します。
2技術的には、「GNU getopt
」は誤称です。このバージョンは、GNUプロジェクトではなくLinux用に実際に作成されました。ただし、これはすべてのGNU規則に準拠しており、「GNU getopt
」という用語が一般に使用されています(FreeBSDなど)。