首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >捕捉:小的与梅森不相容?

捕捉:小的与梅森不相容?
EN

Stack Overflow用户
提问于 2021-08-17 01:44:47
回答 1查看 62关注 0票数 2

作为一般策略,我避免使用后排,而是依赖于捕捉:微小系统调用。

代码语言:javascript
复制
my ( $stdout, $stderr, @results ) = capture { system($command) };

然而,当我在Capture::Tiny下使用之前从未见过的异常时,我只是遇到了HTML::Mason内部的一个异常。

代码语言:javascript
复制
 Error from open(GLOB(0x555ef4527090), >&-1): Invalid argument at /usr/share/perl5/vendor_perl/Capture/Tiny.pm line 107.
    Capture::Tiny::_open(GLOB(0x555ef4527090), ">\\x{26}-1") called at /usr/share/perl5/vendor_perl/Capture/Tiny.pm line 194
    Capture::Tiny::_open_std(HASH(0x555ec25b12b8)) called at /usr/share/perl5/vendor_perl/Capture/Tiny.pm line 391
    Capture::Tiny::_capture_tee(1, 1, 0, 0, CODE(0x555f05d5ce70)) called at InternalModule.pm line 41
    ...
    InternalModule.pm called at /.../apache/htdocs/autohandler line 84
    HTML::Mason::Commands::__ANON__() called at /usr/share/perl5/vendor_perl/HTML/Mason/Component.pm line 135

这是一个遗留系统,所以模块版本有点旧。

Capture::Tiny中执行一些内部操作显示,此方法正在引发异常

代码语言:javascript
复制
sub _open {
  open $_[0], $_[1] or Carp::confess "Error from open(" . join(q{, }, @_) . "): $!";   # Line 107
  # _debug( "# open " . join( ", " , map { defined $_ ? _name($_) : 'undef' } @_ ) . " as " . fileno( $_[0] ) . "\n" );
}

具体来说,调用_open并导致异常的是STDOUT的开放:

代码语言:javascript
复制
# In some cases we open all (prior to forking) and in others we only open
# the output handles (setting up redirection)
sub _open_std {
  my ($handles) = @_;
  _open \*STDIN, "<&" . fileno $handles->{stdin} if defined $handles->{stdin};
  _open \*STDOUT, ">&" . fileno $handles->{stdout} if defined $handles->{stdout};   # Line 194
  _open \*STDERR, ">&" . fileno $handles->{stderr} if defined $handles->{stderr};
}

我尝试过本地化*STDOUT,尽管看起来Capture::Tiny已经这样做了。

现在我的结论是,我应该用这样的解决方案

代码语言:javascript
复制
system("program args 1>program.stdout 2>program.stderr");

关于Capture::Tiny,我还缺少什么东西让它在Mason下工作吗?

EN

回答 1

Stack Overflow用户

发布于 2021-08-18 03:08:21

在后台使用Capture::Tinysystem调用有几个好处

  • 可以更详细地检查和报告错误情况。
  • stdout和stderr的单独信息
  • 没有任何东西被保存到磁盘上(因此,将敏感信息暂时保存在文件系统上)

但是,在本例中,我决定编写备份方法,以防Capture::Tiny在任何特定环境中不可用。如果不是,那么我们将只输出这些流来临时文件,并摄入它们的后缀。

代码语言:javascript
复制
# Capture::Tiny has an incompatibility with Mason.  Therefore we simply need to
# detect if it's safe to use, and if not we should do another mechanism for
# capturing the results.
state $is_safe_to_use_capture_tiny = eval {
    capture sub { };
    1;
};

my ( $stdout, $stderr, @result );

if ($is_safe_to_use_capture_tiny) {
    ( $stdout, $stderr, @result ) = capture { system($command) };

} else {
    # Backup equivalent to Capture::Tiny
    #     There is some risk to this approach, because we are choosing to cache
    # the stdout and stderr results to a file temporarily.  If these results
    # of the system call include sensitive information, then it would exist on
    # disk momentarily.
    #     However, given this is just a backup method that is only needed in
    # the case of system calls under Mason which is front end servers that do not
    # have access to sensitive information, it's an okay sacrifice.

    my $stdout_file = tempfile();
    my $stderr_file = tempfile();

    @result = system(qq{$command 1>$stdout_file 2>$stderr_file});
    $stdout = $stdout_file->exists ? $stdout_file->slurp : '';
    $stderr = $stderr_file->exists ? $stderr_file->slurp : '';
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68810780

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档