gpt4 book ai didi

perl - 如何让 Capture::Tiny 在失败时打印 stderr 和 stdout?

转载 作者:行者123 更新时间:2023-12-04 00:51:36 26 4
gpt4 key购买 nike

我正在尝试通过 Capture::Tiny 获取命令失败时的输出,

#!/usr/bin/env perl

use strict;
use warnings;
use feature 'say';
use Carp 'confess';
use Capture::Tiny 'capture';

sub execute {
my $cmd = shift;
my ($stdout, $stderr, $exit) = capture {
system( $cmd ); # the script dies here
};
if ($exit != 0) { # the script should die here
say "exit = $exit";
say "STDOUT = $stdout";
say "STDERR = $stderr";
confess "$cmd failed";
}
say "STDOUT = $stdout";
say "STDERR = $stderr";
say "exit code = $exit";
return 0
}

execute("ls fakedir");

但问题是当我执行脚本时,

con@V:~/Scripts$ perl execute.pl
"ls fakedir" unexpectedly returned exit value 2 at /home/con/perl5/perlbrew/perls/perl-5.32.0/lib/site_perl/5.32.0/Capture/Tiny.pm line 382.

我得到的只是退出值,它没有提供 fakedir 不存在的有值(value)信息。也就是说,当脚本成功时,我只会得到 STDOUT 和 STDERR。

无论我使用 die 还是 confess 我都会遇到同样的问题 -> 脚本不打印输出 $stderr$标准输出

我已经按照 How do you capture stderr, stdout, and the exit code all at once, in Perl? 上的建议尝试了 IO::CaptureOutput ,这就是我想要的,但是作者 https://metacpan.org/pod/IO::CaptureOutput说“维护者不再推荐此模块 - 请参阅 Capture::Tiny。”这很奇怪,IO::CaptureOutput 似乎工作得更好!

我怎样才能让这个脚本在 $stdout$stderr$exit 上打印 confess?

最佳答案

Capture::Tiny工作正常。 system 正在引发错误,就好像 use autodie "system"在。 Capture::Tiny 仅捕获 STDOUT 和 STDERR,它不会捕获错误。

您必须进行错误处理。您可以使用 eval block 捕获它。

    my ($stdout, $stderr, $exit) = capture {
eval {
system( $cmd );
}
};
if (my $e = $@) { # the script should die here
# Can't get the system exit code from autodie.
#say "exit = $exit"
say "STDOUT = $stdout";
say "STDERR = $stderr";
confess "$cmd failed";
}
else {
say "STDOUT = $stdout";
say "STDERR = $stderr";
say "exit code = $exit";
return 0;
}

在这种特定情况下,您已经在做 autodie 所做的事情。关闭捕获 block 内的 autodie 更简单。

    my ($stdout, $stderr, $exit) = capture {
no autodie "system";
system( $cmd );
};
if ($exit) {
say "exit = $exit";
say "STDOUT = $stdout";
say "STDERR = $stderr";
# the script should die here
confess "$cmd failed";
}
else {
say "STDOUT = $stdout";
say "STDERR = $stderr";
say "exit code = $exit";
return 0;
}

或者,既然你无论如何都会出错,你可以让 autodie 做它的事情。

    my ($stdout, $stderr, $exit) = capture {
system( $cmd );
};
say "STDOUT = $stdout";
say "STDERR = $stderr";
say "exit code = $exit";

关于perl - 如何让 Capture::Tiny 在失败时打印 stderr 和 stdout?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66016077/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com