GETOPT(1)

名称
getopt - コマンドラインオプションの解釈を行う

書式
args=`getopt optstring $*` ; errcode=$?; set -- $args

解説
getopt ユーティリティは、 シェルプロシジャによって簡単に解釈できるようにコマンドライン上の オプションを切り分けます。そして、正しいオプションであるかを確かめます。 optstring は、認識されるオプション文字の文字列です ( getopt(3) を参照)。 オプション文字のあとにコロン (``:'') がある場合、そのオプションは、 (空白文字で区切られているかもしれない) 引数を持つことになります。 特別なオプション ‘--’ は、オプションの終りを区別するために使われます。 getopt ユーティリティは、オプションの最後に引数として ‘--’ を配置します。または、それが陽に使われた時はそれを終りと認識します。 シェル変数 ($1 $2 ...) は、個々のオプションが ‘-’ に続くように再設定されます。そして、それ自身をシェル変数にします。 各オプション引数は、同様にそれ用のシェル変数に入れられます。

使用例
以下のコードの断片は、 引数無しの -a, -b オプションと、 引数ありの -o オプションを取ろうとしているコマンドのために、どのようにして 引数を処理するのかを示しています。

    args=`getopt abo: $*`
    # `getopt abo: "$@"` を使ってはなりません。
    # 以下の set コマンドとは異ったように、引き数を解釈してしまうためです。
    if [ $? != 0 ]
    then
    	echo 'Usage: ...'
    	exit 2
    fi
    set -- $args
    # set コマンドを、バッククォートした getopt と共に、直接使用できません。
    # getopt の終了コードが set のもので隠されてしまうからです。
    # set の終了コードは 0 と定義されています。
    for i
    do
    	case "$i"
    	in
    		-a|-b)
    			echo flag $i set; sflags="${i#-}$sflags";
    			shift;;
    		-o)
    			echo oarg is "'"$2"'"; oarg="$2"; shift;
    			shift;;
    		--)
    			shift; break;;
    	esac
    done
    echo single-char flags: "'"$sflags"'"
    echo oarg is "'"$oarg"'"

このコードは、以下の (コマンド指定の) 例のどれでも同じように 受け入れます。

    cmd -aoarg file file
    cmd -a -o arg file file
    cmd -oarg -a file file
    cmd -a -oarg -- file file

関連項目
sh(1), getopt(3)

診断
getopt ユーティリティは、 optstring 中に含まれていないオプション文字に出会った時に、 標準エラー出力にエラーメッセージを表示し、0 より大きな状態で終了します。

歴史
Bell Labs のマニュアルを元に、 Henry Spencer が書きました。 振舞いは、Bell Labs 版と同じであると信じています。 使用例は FreeBSD バージョン 3.2 と 4.0 で変更しました。

バグ
getopt(3) が持っているバグは、そのまま持っています。

空白文字やシェルのメタキャラクタを含んだ引数は、一般に元のまま 残りません。 これは直すのは簡単に思われますが、そうではありません。 getopt や本マニュアルの使用例を直そうとする人は、 FreeBSD 中のこのファイルの履歴を確認すべきです。

不正なオプションに対するエラーメッセージは、 getopt を実行するシェルプロシジャから返すのではなく、 getopt から返されます。 これも直すのは困難です。

シェルオプションの値を分離すること無く、引数を指定するための set コマンドを使うためのとっても良い方法は、シェルのバージョンを 変えることです。

引き数を部分的に正しく解釈するために、 各シェルスクリプトは (前記使用例のような) 複雑なコードを持つ必要があります。 より良い getopt 的ツールは、複雑な部分の大半をツールの中に移動し、 クライアントのシェルスクリプトを単純にするものでしょう。