「 STD シリーズ 」のコネクションを変更する
前回の記事では、 「 select 」演算子を利用して、標準出力 ( STDOUT ) のコネクションを任意に変更しましたが、「 open 」演算子に対して、「 STD シリーズ 」を指定すると、STDOUT に限らず、そのコネクションを変更することが出来る様です。
例えば、STDIN のコネクションを変更する場合は、次の様に指定します。
open STDIN, '<', 'input_file' or die "Message: $!";
STDOUT や STDERR の場合は、次の様に指定します。モードは「 > 」でも「 >> 」でも構いません。
open STDOUT, '>', 'output_file' or die "Message: $!";
open STDERR, '>>', 'output_file' or die "Message: $!";
open に失敗して die が発動した場合は、それぞれ標準状態でコネクションが開かれます。
自作プログラムのエラーログファイルを作成する
open 演算子で次の様に STDERR を指定すれば、個人的なプログラムのエラーログを作成することが出来ます。
open STDERR, '>>', '/var/log/myperl_err.log' or die "Message: $!";
これによって、システムパス /var/log/ のファイル「 myperl_err.log 」にエラーの内容が書き込まれる様になります。
と、ありますが、どうも手元の環境ではうまく行きません。
あれこれ試してみたところ、次の様に、die を発動した場合のメッセージであれば、キャッチ出来ることを確認しました。
open STDERR, '>>', '/var/log/myperl_err.log' or die "Message: $!";
my $num = 1;
if ( $num == 1 ) {
die "if statements error";
}else{
print "$num\n";
}
1 行目で、STDERR の出力先を、/var/log/myperl_err.log というファイルに指定しています。
3 行目の「 my $num = 1; 」は、if 文の条件に使うために使うために書きました。
5 行目からの if 文で、あえて die を発動する様にしています。今回は意図的に die を発生させているので、システムからのエラーメッセージを表示する「 $! 」は省いています。
これを実行すると、open で指定したログファイルには次の様に書き込まれます。
if statements error at yourfile line n.
もっと単純に、次の様にしても、同様の結果が得られます。
open STDERR, '>>', '/var/log/myperl_err.log' or die "Message: $!";
die "if statements error";
次の様にすれば、ファイル open に失敗した旨のシステムメッセージも得ることが出来ました。
3 行目の open は、die を発動させるために、存在しないファイルを指定しています。
open STDERR, '>>', '/var/log/myperl_err.log' or die "Message: $!";
open FILE, '<', 'notexists' or die "Open error : $!"; # $! を指定
0x4c -> 0x4d へ
今回の検証で、die 以外のエラーメッセージをなぜ捕捉出来なかったのか、今の僕にはその詳細がわかりません。
perldoc.jp の「 perlfaq8 - システムとの相互作用 」に「
制御文字やシグナルをトラップするには? 」という項目がありました。
この中で、「 %SIG ハッシュ」を使って、制御文字のシグナルをトラップするとあります。もしかするとこれが関係するかもしれないと思っています。
また、open によって STD シリーズをコントロールするのは、
perldoc.jp - perlipc によると、プロセス間通信をコントロールする場合に有用だと書いてあります。
例によって、今の僕には遠い世界のお話ですが、今後の学習と経験によって身近なものになることを期待しています。
参考情報は書籍「 初めての Perl 第 6 版 」を中心に perldoc, Wikipedia および各 Web サイト。それと詳しい先輩。
目次 - Perl Index