如何使用 tie() 仅为某些包重定向 STDOUT、STDERR?

2024-03-08

我需要使用一些不幸记录诊断的库 发送至 STDOUT 和 STDERR 的消息。通过使用tie,我可以重定向那些 写入捕获这些的函数。既然我不想要全部 我的程序的 STDOUT 和 STDERR 输出通过 捆绑手柄,我只想对某些包裹执行此操作。

我提出了一个确定实际行为的解决方案 通过查看 caller() 如下所示,但我有这种感觉 必须有更好的方法...有更优雅的解决方案吗?

package My::Log::Capture;
use strict;
use warnings;
use 5.010;

sub TIEHANDLE {
    my ($class, $channel, $fh, $packages) = @_;
    bless {
        channel => lc $channel,
        fh => $fh,
        packages => $packages,
    }, $class;
}

sub PRINT {
    my $self = shift;
    my $caller = (caller)[0];
    if ($caller ~~ $self->{packages}) {
        local *STDOUT = *STDOUT;
        local *STDERR = *STDERR;
        given ($self->{channel}) {
            when ('stdout') {
                *STDOUT = $self->{fh};
            }
            when ('stderr') {
                *STDERR = $self->{fh};
            }
        }
        # Capturing/Logging code goes here...
    } else {
        $self->{fh}->print(@_);
    }
}

1;

package main;

use My::Foo;
# [...]
use My::Log::Capture;
open my $stderr, '>&', *STDERR;
tie *STDERR, 'My::Log::Capture', (stderr => $stderr, [qw< My::Foo >]);
# My::Foo's STDERR output will be captured, everyone else's STDERR
# output will just be relayed.

除了修复库之外,我只能想到一种可能更好的解决方案。

您可以重新打开STDOUT and STDERR文件句柄转换为您自己的文件句柄。然后,重新打开STDOUT and STDERR和你绑着的把手。

例如,您可以这样做STDOUT:

open my $fh, ">&", \*STDOUT or die "cannot reopen STDOUT: $!";
close STDOUT; 

open STDOUT, ">", "/tmp/test.txt"; 

say $fh "foo"; # goes to real STDOUT
say "bar";     # goes to /tmp/test.txt

你可以阅读perldoc -f 打开 http://perldoc.perl.org/functions/open.html有关“>&”之类的所有详细信息。

无论如何,您可以用绑定文件句柄的设置替换该打开调用,而不是“/tmp/test.txt”。

您的代码必须始终使用显式文件句柄来写入或使用select http://perldoc.perl.org/functions/select.html切换文件句柄:

select $fh;
say "foo"; # goes to real STDOUT

select STDOUT;
say "bar"; # goes to /tmp/test.txt
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 tie() 仅为某些包重定向 STDOUT、STDERR? 的相关文章

随机推荐

  • Azure 网站和 Sass

    我一直在尝试寻找是否有一种方法可以通过 windows azure 网站支持 sass 有人可以向我指出一些文档吗 或者如果可能的话现在就让我知道 我特别希望支持祖布基金会 http foundation zurb com index ht
  • Pandas:如果预定义列表中不存在,则将列值替换为空

    我有一个清单 X 其中包含列的一组合法值 说吧 我有专栏A 我想替换 设置 为空字符串 中的元素df A 如果它们的值不在 X 中 我怎样才能在 Pandas 中有效地做到这一点 我知道有isin 但这只是检查值是否存在并返回一系列 Tru
  • 通过Windows中的命令行工具合并两个png?

    我正在寻找一个可以通过命令行 Windows 7 使用的工具来合并两个相同大小的 png 到目前为止 我在搜索方面运气不佳 因为我见过的大多数工具都是相当笨重的应用程序 它们似乎不针对简单的操作 我想用覆盖图像中的非透明像素覆盖不透明基本图
  • 情节 orca 无法在 aws ec2 实例上工作

    我跟着this https github com plotly orca安装conda plotly orca在 AWS EC2 实例上 构建于anaconda python3图像 但击中Cannot open shared object调
  • WIX如何从自定义操作访问源文件

    我有一个 WIX 安装应用程序和许多源文件
  • 如何防止行高在顶部添加边距?

    每当我使用大line height like 1 6em它总是在文本的最顶部添加我不想要的边距 例子 http jsfiddle net EstpJ 1 http jsfiddle net EstpJ 1 我希望文本的边框清晰 并且没有任何
  • 分布式erlang安全如何?

    我想要有 2 个独立的 erlang 节点可以相互通信 so node a myhost将能够发送消息至b myhost 有没有办法限制节点a myhost 所以只有来自 a 的函数安全模块可以被召唤b myhost 它应该是这样的 a m
  • twitter bootstrap - 背景颜色

    我正在尝试更改引导程序的背景颜色和不透明度 我有以下 CSS well opacity 0 9 opacity 0 1 moz opacity 0 9 opacity 0 1 webkit opacity 0 9 opacity 0 1 b
  • CodeIgniter 中视图中的 $this 关键字

    我试图理解如何 this gt load gt view works insideCodeIgniter 中的视图文件的一部分 core Controller php 正在调用 core Loader php 然后调用 ci load 后者
  • 读取thunderbird地址mab文件内容

    我的 TBIRD 地址簿上有几个地址列表 每次我需要编辑包含在多个列表中的地址时 查找哪个列表包含要修改的地址都是一件很痛苦的事情 作为一个帮助工具 我想阅读几个文件 并只给用户一个列表 xxx MAB 文件仅包含一次搜索的搜索地址 有了生
  • 在 R 中将字符串拆分为新行[重复]

    这个问题在这里已经有答案了 我有一个如下数据集 Country Region Molecule Item Code IND NA PB102 FR206985511 THAI AP PB103 BA 107603 F000113361 10
  • PHPUnit、接口和命名空间 (Symfony2)

    我目前正在为 Symfony2 开发一个开源包 并且真的希望它在单元测试覆盖率和一般可靠性方面成为最优秀的 但是由于我缺乏 PHPUnit 知识 或复杂的场景 谁知道 目前 我有一个 Mailer 类 用于处理个人邮件场景 它看起来有点像这
  • 找不到 docker 命令

    我在Mac上安装了docker 安装成功 它还正在运行 并尝试在终端中执行以下命令 docker v 请参阅以下错误 bash docker command not found 我该如何解决这个问题 在 Windows 中这些命令运行良好
  • 需要指南针陀螺仪帮助

    我需要一个游戏对象指向北方 并且我想将其与 gyro attitude 输入结合起来 我曾尝试一步完成此任务 但没有成功 也就是说 我无法制作任何我在网上找到的陀螺仪脚本 以满足始终指向北方的额外要求 相信我 我已经尝试了所有能找到的关于这
  • Angular2 RC6 - 在我的子模块中导入 BrowserModule

    I have DashboardModule导入到我的根目录中AppModule 在组件模板中DashboardModule I use ngFor 它声明于BrowserModule 正是在CommonModule进口者BrowserMo
  • database.yml 中的 pool 选项有什么用

    database yml 中最广泛使用的选项如下 adapter encoding database pool username password socket host port timeout 上面大部分的用法我都知道 除了pool 所
  • 如何将一个数字分成多个部分,使结果之和等于输入?

    我试图将一个数字分成多个部分 以便各部分的总和等于输入数字 如果我有 3 99 并且需要分成两部分 则预期输出为 2 和 1 99 2 1 99 3 99 如果我需要将 3 99 分成 3 部分 则预期输出为 1 3 1 3 和 1 39
  • opencv矩阵存入共享内存

    我想在两个 Linux 进程之间共享一个 CvMat 对象 OpenCV 库中的矩阵 为此我使用共享内存 一个进程 服务器 将从网络摄像头捕获一帧 矩阵 将其转换为灰度 使用共享内存共享它并在屏幕上显示该帧 另一个进程 客户端 将读取共享帧
  • Zend 框架 - Zend_Form 装饰器问题

    我有一个像这样扩展 Zend Form 的类 简化 class Core Form extends Zend Form protected static elementDecorators array ViewHelper Errors a
  • 如何使用 tie() 仅为某些包重定向 STDOUT、STDERR?

    我需要使用一些不幸记录诊断的库 发送至 STDOUT 和 STDERR 的消息 通过使用tie 我可以重定向那些 写入捕获这些的函数 既然我不想要全部 我的程序的 STDOUT 和 STDERR 输出通过 捆绑手柄 我只想对某些包裹执行此操