我想将Perl脚本的stdout和stderr复制到一个文件中,同时将其保留在屏幕上,最好在脚本本身内部使用一些技巧。
./test.pl 2>&1 | tee foo.bar
但隐藏在perl脚本实现中。目前我刚刚编写了一个子例程,它将所有消息打印到屏幕上和文件句柄中,但缺点是如果脚本死亡,死亡消息将不会出现在日志中。有没有办法做到这一点?
7uzetpgm1#
请参见“13.15.9.领带示例:多个接收器文件句柄”。主要要知道的是tie *TEE, "Tie::Tee", @handles;注意:Tie::Tee包是你需要自己创建的东西,代码在书中的同一部分。注意:然后你可以执行select(TEE),它将被用在每个常规的print语句中,所以你不需要执行print TEE xxx。注:要使任何STDERRy输出(包括芯片)转到同一文件句柄,请将STDERR更改为TEE,如下所示:
tie *TEE, "Tie::Tee", @handles;
select(TEE)
print
print TEE xxx
use Tie::Tee; use Symbol; @handles = (*STDOUT); push(@handles, $handle = gensym( )); open($handle, ">/tmp/teetest.xxx"); tie *TEE, "Tie::Tee", @handles; select(TEE); *STDERR = *TEE; print "raw print\n"; die "XXXX\n";
输出将为:
raw print XXXX
文件内容为:
krcsximq2#
看一看Log::Dispatch将消息分派到一个或多个输出。
use Log::Dispatch; # Simple API # my $log = Log::Dispatch->new ( outputs => [ [ 'File', min_level => 'debug', filename => 'logfile' ], [ 'Screen', min_level => 'warning' ], ], ); $log->info('Blah, blah'); # More verbose API # my $log = Log::Dispatch->new(); $log->add( Log::Dispatch::File->new ( name => 'file1', min_level => 'debug', filename => 'logfile' ) ); $log->add( Log::Dispatch::Screen->new ( name => 'screen', min_level => 'warning', ) ); $log->log( level => 'info', message => 'Blah, blah' ); my $sub = sub { my %p = @_; return reverse $p{message}; }; my $reversing_dispatcher = Log::Dispatch->new( callbacks => $sub );
它有一些帮助/实用程序模块,你也应该看看。Log::Dispatch::DBI -将输出记录到数据库表。Log::Dispatch::FileRotate -作为其使用的一部分,定期轮换日志文件。Log::Dispatch::File::Stamped -使用日期和时间信息标记日志文件。Log::Dispatch::Jabber -通过Jabber记录消息。Log::Dispatch::Tk -将消息记录到Tk窗口。Log::Dispatch::Win32 EventLog-将消息记录到Windows事件日志。Log::Dispatch::Config -允许通过一个文本文件来配置日志记录,类似于(或者我被告知)如何使用log4j来完成。
9nvpjoqh3#
Capture::Tiny具有T形接头。
kx5bkwkv4#
根据脚本的大小,我强烈推荐Log::Log4perl ...在每次编写脚本时都避免重新实现日志记录。如果您在简单模式下使用Log4perl,它只会添加大约10行代码,非常有用。Log4perl在将输出重定向到几乎任何您想要的地方方面是极其灵活的,包括一次重定向多个输出。
ou6hu8tu5#
This听起来就像你所需要的,不幸的是它是一个bash脚本,你希望这一切都在你的perl代码中处理。
5条答案
按热度按时间7uzetpgm1#
请参见“13.15.9.领带示例:多个接收器文件句柄”。
主要要知道的是
tie *TEE, "Tie::Tee", @handles;
注意:Tie::Tee包是你需要自己创建的东西,代码在书中的同一部分。
注意:然后你可以执行
select(TEE)
,它将被用在每个常规的print
语句中,所以你不需要执行print TEE xxx
。注:要使任何STDERRy输出(包括芯片)转到同一文件句柄,请将STDERR更改为TEE,如下所示:
输出将为:
文件内容为:
krcsximq2#
看一看Log::Dispatch
将消息分派到一个或多个输出。
它有一些帮助/实用程序模块,你也应该看看。
Log::Dispatch::DBI -将输出记录到数据库表。
Log::Dispatch::FileRotate -作为其使用的一部分,定期轮换日志文件。
Log::Dispatch::File::Stamped -使用日期和时间信息标记日志文件。
Log::Dispatch::Jabber -通过Jabber记录消息。
Log::Dispatch::Tk -将消息记录到Tk窗口。
Log::Dispatch::Win32 EventLog-将消息记录到Windows事件日志。
Log::Dispatch::Config -允许通过一个文本文件来配置日志记录,类似于(或者我被告知)如何使用log4j来完成。
9nvpjoqh3#
Capture::Tiny具有T形接头。
kx5bkwkv4#
根据脚本的大小,我强烈推荐Log::Log4perl ...在每次编写脚本时都避免重新实现日志记录。
如果您在简单模式下使用Log4perl,它只会添加大约10行代码,非常有用。
Log4perl在将输出重定向到几乎任何您想要的地方方面是极其灵活的,包括一次重定向多个输出。
ou6hu8tu5#
This听起来就像你所需要的,不幸的是它是一个bash脚本,你希望这一切都在你的perl代码中处理。