概要
Linuxのteeコマンドのように、出力を2つに分けるにはFile::Teeを使うと便利
詳細
出力が長いエラーログを出すバッチジョブで、作業の進行状況や突発的な異常時はリアルタイムの画面で確認したいが、作業終了時にはログファイルで確認しておきたいと思った。
これには、PerlのFile::Teeモジュールを以下のように使用すれば良い。
インストール
モジュールは
$ sudo cpan File::Tee
でインストールしてもいいが、
ぼくはUbuntuのapt-cacheコマンドを使って
$ apt-cache search File::Tee
libfile-tee-perl - Perl module to duplicate streams like the tee unix command
とするとlibfile-tee-perlというのが見つかったので
$ sudo apt install libfile-tee-perl
としてインストールした。
サンプルコード
以下のコードはSTDERRというファイルハンドルを/home/cf/tee.txtにコピーしている。
入口が1つで出口が2つだからT(ティー)と言うそうだ。
#!/usr/bin/perl
# tee.pl
use strict;
use warnings;
use File::Tee qw(tee);
# 出力ファイルのパス
my $logfile = "/home/cf/tee.txt";
# STDERRをteeに設定
tee(\*STDERR, '>>', $logfile);
# ここからのwarn、die、systemコマンドのSTDERR出力はファイルとターミナルの両方に出力されるはす
# テスト出力
warn "aaa \n";
warn "bbbbb \n";
die "ccccccc \n";
実行すると以下のようになる。
$ ./tee.pl # 実行
aaa
bbbbb
cccccc
$ cat ./tee.txt # ログファイルの確認
aaa
bbbbb
cccccc
できてるー。
この場合warn、dieの他にsystemコマンドで外部コマンドを実行したときのエラー出力もtee出来る。
STDOUTをteeすることも、普通のファイルハンドルで2つのファイルを出すことも出来るはず(未確認)。
IO::Teeというのもあるが
なぜかうまくいかなかった。
#!/usr/bin/perl
# tee_failed.pl
use strict;
use warnings;
use IO::Tee;
# 出力ファイルのパス
my $logfile = '/home/cf/logfile.txt';
# IO::Teeを使用してSTDERRをファイルとターミナルに出力
open my $log_fh, '>>', $logfile or die "Could not open log file: $!";
my $tee = IO::Tee->new(\*STDERR, $log_fh);
select $tee;
# ここからのwarn、die、systemコマンドのSTDERR出力はファイルとターミナルの両方に出力されるはす
# テスト出力
warn "aaa \n";
warn "bbbbb \n";
die "ccccccc \n";
何のエラーもなく0バイトのファイルができ、何も入っていない状態になった。
なぜかは追求してません。
ひどくてゴメンネ
(この項終わり)