ホーム > Shell > Shellでgetoptsを使ってコマンドライン引数の解析

Shellでgetoptsを使ってコマンドライン引数の解析

だいぶ前の話、Perlを使わないでShellスクリプトで頑張っていた頃、Shellでコマンドラインオプションの解析をやる時は

#!/bin/sh
 
for OPT in $*
do
    case $OPT in
    '-x' )
        FLAG_X="TRUE"
        ;;
    '-y' )
        shift
        FLAG_Y="TRUE"
        VALUE_Y=$1
        ;;
    esac
 
    shift
done
 
if [ "$FLAG_X" = "TRUE" ]; then
    echo "Option -x specified."
fi
 
if [ "$FLAG_Y" = "TRUE" ]; then
    echo "Option -y $VALUE_Y specified."
fi

という感じで $* と shift を使ってやっていたのですが、最近 getopts なる素敵なビルトインコマンドを知りました。これを使うと上のスクリプトは下のように書き直すことができます。

#!/bin/sh
 
while getopts xy: OPT
do
    case $OPT in
    "x" )
        FLAG_X="TRUE"
        ;;
    "y" )
        FLAG_Y="TRUE"
        VALUE_Y=$OPTARG
        ;;
    esac
done
 
if [ "$FLAG_X" = "TRUE" ]; then
    echo "Option -x specified."
fi
 
if [ "$FLAG_Y" = "TRUE" ]; then
    echo "Option -y $VALUE_Y specified."
fi

スクリプトの行数自体はあんまり変わらないように見えますが、shift 忘れをよくやらかしていたので、それが無くなった分つまらないバグを入れ込まなくなった気がします。

getoptsの解説

getopts の引数にオプションの文字を指定しますが、文字のあとに : (コロン)をつけると、引数ありのオプションという扱いになります。さらに

$ ./getopts.sh -z

のように未定義のオプションを指定すると

/home/oinume/tmp/script/getopts.sh: illegal option -- z

というように怒られます。このエラーハンドリングを自前でやるには :xy: のように、getopts の引数の文字列の最初を : にすればいいみたい。

さらに $OPTIND という変数を下記のように -1 してやることで、オプション以降に与えられた引数を取得することができます。例えば、上のスクリプトに下記を足して

shift `expr $OPTIND - 1`
if [ -n "$1" ]; then
    echo "Argument $1 specified."
fi
$ ~/tmp/script/getopts.sh -x -y yyy hoge

のように実行すると

Option -x specified.
Option -y yyy specified.
Argument hoge specified.

となります。getopts を実行すると、$OPTIND にはオプションのインデックス番号が保存されているので、これを -1 して shift してやることで、オプション以降の引数が取得できるようになるという仕組みです。

最近はこういうレベルのプログラムだったらPerlで書くことも多かったのですが、Shell でも十分いけそうだと実感しました。

詳解 シェルスクリプト

著者/訳者:Arnold Robbins Nelson H. F. Beebe

出版社:オライリージャパン( 2006-01-16 )

大型本 ( 345 ページ )



こちらもあわせてどうぞ


カテゴリー: Shell タグ:
  1. コメントはまだありません。
  1. トラックバックはまだありません。