只需在Perl中使用T,而不使用fork、File::tee或管道连接到T

只需在Perl中使用T,而不使用fork、File::tee或管道连接到T,perl,Perl,在Perl中,有没有一种简单的方法可以将STDOUT或STDERR发送到多个位置,而无需分叉、使用File::Tee或打开到/usr/bin/Tee的管道 当然有一种方法可以在纯perl中实现这一点,而无需编写20多行代码,对吗?我错过了什么?在这里和其他地方都有人问过类似的问题,但没有一个答案能满足我不需要的要求 叉 使用File::Tee/IO::Tee/其他一些模块+依赖项 其代码占用空间比我的实际脚本大1000倍 打开到实际T形三通命令的管道 我可以在这里看到使用核心模块是一种折衷,但这

在Perl中,有没有一种简单的方法可以将STDOUT或STDERR发送到多个位置,而无需分叉、使用File::Tee或打开到/usr/bin/Tee的管道

当然有一种方法可以在纯perl中实现这一点,而无需编写20多行代码,对吗?我错过了什么?在这里和其他地方都有人问过类似的问题,但没有一个答案能满足我不需要的要求

叉 使用File::Tee/IO::Tee/其他一些模块+依赖项 其代码占用空间比我的实际脚本大1000倍 打开到实际T形三通命令的管道
我可以在这里看到使用核心模块是一种折衷,但这真的是必要的吗?

看起来我可以简单地做到这一点:

BEGIN {
  open my $log, '>>', 'error.log' or die $!;

  $SIG{__WARN__} = sub { print $log @_ and print STDERR @_ };

  $SIG{__DIE__} = sub { warn @_ and exit 1 };
}
这简单有效地将大多数错误消息发送到原始的STDERR和日志文件中,我被告知,显然在eval中捕获的东西不会出现。因此,评论中提到了这一点的缺点。但正如原问题所述,需要是具体的。这不是为了重复使用。这是一个简单的小脚本,它的长度永远不会超过100行

如果您正在寻找一种方法来实现这一点,而不是一个黑客,下面是改编自


如果你坚持的话,你可以手动复制。重定向标准流,捕获其内容,然后将其放到多个位置。您可以将其打包到几个整洁的子例程中。为什么会有这些要求?你所要求的并不像你的问题听起来那么简单。说到模块和代码行,我们不能既有蛋糕又有蛋糕。为了使它们具有普遍的用途,必须有更多的代码,而不仅仅是为了解决您或我当前的需要。如果您必须执行其他操作,请严格按照您所说的操作:在子例程中执行几行代码。请注意,您还可以使用select在打印目的地之间切换。我没有询问模块与脚本相比有多大。我问你为什么认为它们比应该的大,因为你问我们的是一个较短的版本,我知道。读我说的话。还不到一半。它甚至和你想要什么都没有关系。或者您没有意识到文件句柄不是在使用时执行的子例程?它们只是标识符或数据结构问题,但这根本不是您要问的问题。它不会影响打印到STDOUT的内容,只有打印到STDERRIt的部分内容是好的,您已经找到了问题的解决方案。做得好。我想很少有人会认为这是一个避免使用普通方法的简单方法,但是你的发现是无用的,这甚至不能解决问题的要求。尽管两个都是你写的。
use IO::Tee;

open my $save_stderr, '>&STDERR' or die $!;

close STDERR;

open my $error_log, '>>', 'error.log' or die $!;

*STDERR = IO::Tee->new( $save_stderr, $error_log ) or die $!;