EmptyPage.jp > Notes > Perl スクリプトでのコマンドラインオプション処理

Perl スクリプトでのコマンドラインオプション処理

公開 2006年8月25日、 更新 2009年1月17日

Perl でコマンドラインオプションを処理するときの覚え書き。基本的ないし実用的な事項のみで、中級以上のトピックはばっさり省いています。Perl ドキュメントをもとに作成しました。

1. 基礎知識

2. GetOptions 関数

コマンドラインオプションを処理するには Getopt::Long モジュールの GetOptions 関数を使う。

use Getopt::Long;

以下のコード例では use Getopt::Long; は省略している。

2.1. 単独で指定するオプション

my $opt_all = 0;
my $opt_debug = 0;

GetOptions('all' => \$opt_all, 'debug' => \$opt_debug);

print "\$opt_all: $opt_all\n";
print "\$opt_debug: $opt_debug\n";
H:\>foo.pl --all --debug
$opt_all: 1
$opt_debug: 1

長いオプション名 (--all) から短いオプション名 (-a) が自動的に作られる。これは単独で指定するオプションに限らずすべてのオプションで同様。同じ頭文字で始まるオプションが混在している場合は、オプションを特定できるまでの数文字を打つ必要がある(例: オプションとして --head--help が使える場合、短縮形はそれぞれ -hea -hel となる)。

H:\>foo.pl -a -d
$opt_all: 1
$opt_debug: 1

GetOptions 関数でオプション名に ! を付けると、--nohoge という指定によりそのオプションを明示的にオフにできるようになる。

my $opt_all = 0;
my $opt_debug = 0;
my $opt_cache = 1;

GetOptions('all' => \$opt_all, 'debug' => \$opt_debug, 'cache!' => \$opt_cache);

print "\$opt_all: $opt_all\n";
print "\$opt_debug: $opt_debug\n";
print "\$opt_cache: $opt_cache\n";
H:\>foo.pl
$opt_all: 0
$opt_debug: 0
$opt_cache: 1

H:\>foo.pl --nocache
$opt_all: 0
$opt_debug: 0
$opt_cache: 0

ちなみにこの場合 -n--nocache と等価になってもよさそうだが、そうはならない。短縮形は -noc になる。

また、オプション名に + を付けると、複数回指定したときにその回数が蓄積されるようになる。

my $opt_all = 0;
my $opt_debug = 0;
my $opt_cache = 1;

GetOptions('all' => \$opt_all, 'debug+' => \$opt_debug, 'cache!' => \$opt_cache);

print "\$opt_all: $opt_all\n";
print "\$opt_debug: $opt_debug\n";
print "\$opt_cache: $opt_cache\n";
H:\>foo.pl -d -d
$opt_all: 0
$opt_debug: 2
$opt_cache: 1

2.2. 引数付きオプション

GetOptions に渡すオプション名の後ろに =s を付けると、オプションに文字列引数をとることができるようになる。=i を付けると整数引数をとれる(型指定はもちろんこのほかにも用意されている)。

my $name = 'John Doe';
my $count = 1;

GetOptions('name=s' => \$name, 'count=i' => \$count);

print "Hello, $name.\n" x $count
H:\>foo.pl
Hello, John Doe.

H:\>foo.pl -n Kim -c 3
Hello, Kim.
Hello, Kim.
Hello, Kim.

ちなみに、引数つきオプションは --name=value という形式でもよい。たとえば上記の例では foo.pl -n=Kim -c=3 と実行しても同じ結果を得ることができる。

複数回指定された引数つきオプションを配列で受け取ることもできる。

my @names = ();

GetOptions('name=s' => \@names);

for (@names) {
    print "Hello, $_.\n";
}
H:\>foo.pl -n Kim  -n Lee -n Steve -n Thurston
Hello, Kim.
Hello, Lee.
Hello, Steve.
Hello, Thurston.

2.3. オプションをハッシュに格納する

オプションが多くなってくると、それぞれに変数を用意するやり方では扱いにくくなる。GetOptions 関数ではオプションをハッシュ(連想配列)変数に格納することもできる。これにより、たとえば --width 10 --height 20 というオプションに $opts{width} $opts{height} というようにアクセスできるようになる。

my %opts = ();

GetOptions(\%opts, 'verbose', 'name=s');

if ($opts{verbose}) {
    print "Hello, $opts{name}.\n";
} else {
    print "Hi, $opts{name}.\n";
}

GetOptions 関数の引数の並びに注意! オプションを格納するハッシュ変数は第1引数になっている。

H:\>foo.pl -n Kim
Hi, Kim.

H:\>foo.pl -n Kim -v
Hello, Kim.

3. もっと詳しく

Getopt::Long モジュールのドキュメントにはオプション解析の処理をより細かく制御する方法や引数つきオプションのここで紹介していない型定義の情報などが載ってます。上記の内容で物足りないと思ったらマニュアルを読んでみましょう(ただし深入りしないように)。

4. 最後に

GetOpt::Long とミスタイプしないようにしましょう。

5. 改訂履歴

2006-10-30
デフォルトで短いオプションを連続で指定できる(-a -b-ab とできる)という記述は誤りだったので削除した。
2006-08-25
公開。