I'm trying to go through Capture::Tiny
to get output of a command upon failure,
#!/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");
but the problem is that when I execute the script,
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.
all I get is the exit value, which doesn't give the valuable information that fakedir
doesn't exist. That is, I only get STDOUT and STDERR when the script succeeds.
Whether I use die
or confess
I get the same problem -> the script doesn't print the output $stderr
and $stdout
I've tried IO::CaptureOutput
as suggested on How do you capture stderr, stdout, and the exit code all at once, in Perl?, which does what I want, but the author https://metacpan.org/pod/IO::CaptureOutput says "This module is no longer recommended by the maintainer - see Capture::Tiny instead." This is strange, IO::CaptureOutput seems to work much better!
How can I get this script to die with $stdout
, $stderr
, and $exit
printed with confess?
system $cmd
do if you run it outsidecapture
? If it dies you will have to trap that with an eval. It shouldn't die, but that shouldn't be Capture::Tiny's fault. – Schwernuse autodie "system"
which will causesystem
to die on failure which you'd have to trap with aneval
block insidecapture
(orno autodie
in the capture block). Check your environment that you're not shadow loading autodie, that would be Bad. – SchwernCapture::Tiny
version 0.48. I could've sworn that I wasn't using autodie, but I like autodie because it captures errors in other parts of the scripts. Indeed, that may be the problem. For this reason, I think thatIO::CaptureOutput
may be superior toCapture::Tiny
because it allowsautodie
to work properly – con