Perl Hackers Hub

第45回 Perlで作るコマンドラインツール―オプション,サブコマンド,設定ファイルへの対応(1)

この記事を読むのに必要な時間:およそ 5 分

本連載では第一線のPerlハッカーが回替わりで執筆していきます。今回のハッカーはふしはらかんさんで,テーマは「Perlで作るコマンドラインツール」です。

本稿のサンプルコードは,本誌サポートサイトから入手できます。

コマンドラインツールを作ろう

本連載を読まれているみなさんは,コマンドラインツールを使ったことのある人がほとんどかと思います。また,コマンドラインツールを作ったことのある人も多いでしょう。Perlはほとんどの環境に標準で導入されていて,強力なテキスト処理を備えていることもあり,シェルスクリプトで書くのはしんどいかなという程度のものから,かなり複雑で高負荷な処理を要するものまで,幅広くコマンドラインツールの記述に使われています。

今回は,コマンドラインツールをPerlで作る場合に使用すると便利なモジュールを,コマンドライン引数解析ライブラリであるSmart::Optionsを中心に紹介していきます。

Smart::Optionsによるコマンドライン引数の利用

コマンドラインツールを実行する際に,プログラム名に続いて渡す文字列をコマンドライン引数と言います。本節では,コマンドライン引数とそれを使ったオプションの渡し方の仕様から,Smart::Optionsの具体的な使い方までを見ていきましょう。

コマンドライン引数はなぜ必要か

コマンドライン引数は空白で区切って複数の値を渡すのが基本ですが,さまざまな設定値をオプションとして渡せるようになっている場合が多く,その仕様がPOSIXPortable Operating System Interface for UNIXやGNUでガイドラインとして定められています。

$ command -a -bc -d オプション値 --execute --file=/path/
to/file 引数1 引数2 引数3

-(ハイフン)から始まる英字1字(例:-aがオプション名です。-bcのように英字を複数書くと複数のオプションを一度に指定できます。

オプションに値を持たせる場合,-d オプション値のように空白を空けてから値を書きます。もし値に空白を含めたい場合は,値全体を-d "値 値"のようにダブルクオートで囲みます。

オプション名を2文字以上にしたい場合は--(ハイフン2文字)から始めるようにします(例:--execute)⁠この場合,値を渡す場合に空白を空けるだけなく,=(イコール)で結ぶ書き方を使うこともできます(例:--file=path)⁠GNUスタイルでは,--versionでのバージョン表示と,--helpでのUsage(コマンドの使い方)の表示が必須です。

多くのプログラミング言語では,コマンドライン引数を空白で区切った文字列の配列として受け取れるようになっています。Perlもコマンドライン引数を特殊変数@ARGVとして参照できるようになっています。

cmd.pl


#!/usr/bin/perl

use strict;
use warnings;

print join("\n", @ARGV);

このコードを実行すると,渡されたコマンドライン引数を改行で区切って出力します。

$ perl cmd.pl -a -bc -d FooBar arg1 arg2
-a
-bc
-d
FooBar
arg1
arg2

引数をシンプルに利用する

前項のサンプルコードでコマンドライン引数を配列として取得できましたが,それをPOSIXスタイルに沿ったオプションとして扱うのは手間です。たとえば-bcというオプションからbオプションとcオプションが有効になっていることを知ったり,dオプションの値としてFooBarが渡されていることを知ったりするには,@ARGVを解析するプログラムを実装する必要があります。

PerlにはGetOpt::Longというモジュールが標準添付されているほか,CPANにさまざまなコマンドライン引数解析ライブラリが登録されていて,それらを使ってコマンドライン引数の解析ができます。今回はその中から,拙作のSmart::Optionsというライブラリを紹介します。

Smart::OptionsはNode.jsのコマンドライン引数解析ライブラリであるoptimistを参考に実装したもので,前述のPOSIX,GNUスタイルなオプション値をシンプルな書き方で解析して使えるようにしたものです。試しに先ほどのコードをSmart::Optionsを使った形にあらためてみます。

cmd_smart.pl


#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;
use Smart::Options;

print Dumper(argv(@ARGV));

argv()Smart::Optionsによってインポートされた関数で,引数に渡された配列を解析してハッシュリファレンスの形で返します。Data::Dumperでハッシュの中身をそのまま出力しているので,このコードを実行すると次のようになります。

$ perl cmd_smart.pl -a -bc -d FooBar arg1 arg2
$VAR1 = {
    '_' => [
            'arg1',
            'arg2'
            ],
    'd' => 'FooBar',
    'c' => 1,
    'b' => 1,
    'a' => 1
};

結果を見てわかるとおり,オプションの項目名-a-bなど)がハッシュのキーになり,オプションの値がハッシュの値として登録されています。また,オプションに関わらないただの引数はキー名が_の項目に配列リファレンスの形で登録されています。-aなどの値を持たないオプション(フラグ)は,Perlで真trueになる1が値として入っていますので,

my $opt = argv();
if ($opt->{a}) {
    # -aが渡されたときにやる処理
}

のように書けます。ちなみにこのコードではargv()に引数を渡していませんが,その場合は@ARGVを引数として使用します。

このようにSmart::Optionsを導入してargv()を使うだけで,コマンドライン引数からオプション値を取り出すのが簡単になります。

コメント

コメントの記入