#!/usr/bin/perl # # getopts-template.pl # use Getopt::Std ; sub usage_exit { print STDERR "Usage: getopts-template.pl [-a] [-d dir] item1 item2 ...\n" ; exit 1 ; } print "@ARGV\n" ; ####DEBUG { local $SIG{__WARN__} = \&usage_exit ; if (getopts("ad:h") != 1) { usage_exit ; } } if (defined $opt_h) { usage_exit ; } $argc = scalar @ARGV ; print "\$argc=$argc\n" ; ####DEBUG print "\@ARGV=@ARGV\n" ; ####DEBUG print "\$opt_a=$opt_a\n" ; ####DEBUG print "\$opt_d=$opt_d\n" ; ####DEBUG要所だけ補足しますと、
__WARN__ の行を書かない場合、未定義オプションを指定すると、Getopt::Std が自分でエラーメッセージ(Unknown option: x)を出してしまいます。
わたしは、この振る舞いは嫌なので、自分で用意した usage_exit を呼ぶようにしました。
もう1点、引数が必要なオプション -d dir について、dir が省略された場合にエラーにするには、getopts の戻り値を見る必要があります。getopts は、エラーが生じると、1 以外の値を返します。
実行結果は、次のようになります。
# ./getopts-template.pl -d dir item1 item2 -d dir item1 item2 $argc=2 @ARGV=item1 item2 $opt_a= $opt_d=dirbash の getopts と同じ振る舞いのようで、コマンドラインの後半でオプション指定を書くと、うまく処理できません。うーん、残念です。
# ./getopts-template.pl item1 item2 -d dir item1 item2 -d dir $argc=4 @ARGV=item1 item2 -d dir $opt_a= $opt_d=
2011-09-01追記
getopt(1) を使うテンプレートも作りました。次の記事も参照ください。
perl でオプション解析(getoptコマンド編)
2012-02-11追記
getopts の場合は、-ll のような複数回の指定を区別できないことを知りました。getopt(1) を使う方法ならば対応できますが、コードが長くなるのがいまひとつ。Getopt::Long を使うと、また、別のイライラに遭遇するようです。。。
2017-01-30追記
久々に、このパターンを CentOS 7 で使ったのですが、何やらごちゃごちゃと余計なメッセージが出ました。
[root@hoge tmp]# ./getopts-template.pl --help --help ./getopts-template.pl version [unknown] calling Getopt::Std::getopts (version 1.07 [paranoid]), running under Perl version 5.16.3. Usage: getopts-template.pl [-OPTIONS [-MORE_OPTIONS]] [--] [PROGRAM_ARG1 ...] The following single-character options are accepted: With arguments: -d Boolean (without arguments): -a -h Options may be merged together. -- stops processing of options. Space is not required between options and their arguments. [Now continuing due to backward compatibility and excessive paranoia. See 'perldoc Getopt::Std' about $Getopt::Std::STANDARD_HELP_VERSION.] $argc=0 @ARGV= $opt_a= $opt_d= [root@hoge tmp]#これはちょっと余計なお世話と思って、調べたところ、次のように追加の記述を行うことで、出なくなりました。
[root@hoge tmp]# diff -u getopts-template.pl getopts-template.pl-2017-01-30 --- getopts-template.pl 2017-01-30 22:00:17.954554580 +0900 +++ getopts-template.pl-2017-01-30 2017-01-30 22:02:00.828239598 +0900 @@ -11,6 +11,8 @@ } print "@ARGV\n" ; ####DEBUG +sub HELP_MESSAGE { usage_exit ; } +sub VERSION_MESSAGE { ; } { local $SIG{__WARN__} = \&usage_exit ; if (getopts("ad:h") != 1) { [root@hoge tmp]# ./getopts-template.pl-2017-01-30 --help --help Usage: getopts-template.pl [-a] [-d dir] item1 item2 ... [root@hoge tmp]#Simple is best. ですね。
0 件のコメント:
コメントを投稿