Reputation: 75
I need to run a Perl script from a Perl script, save the output in a log file and display an error message if I get an error. I don't want the script to end, just print the message that a call had failed. I am using capture to do this but I am unable to print the error message conditionally.
I referred to this link, particularly this text:
$EXITVAL The exit value of any command executed by IPC::System::Simple can always be retrieved from the $IPC::System::Simple::EXITVAL variable:
This is particularly useful when inspecting results from capture, which returns the captured text from the command.
use IPC::System::Simple qw(capture $EXITVAL EXIT_ANY); my @enemies_defeated = capture(EXIT_ANY, "defeat_evil", "/dev/mordor");
print "Program exited with value $EXITVAL\n";$EXITVAL will be set to -1 if the command did not exit normally (eg, being terminated by a signal) or did not start. In this situation, an exception will also be thrown.
This is my code:
use IPC::System::Simple qw(capture EXIT_ANY $EXITVAL);
my $output = capture(EXIT_ANY, $tool_path);
if($EXITVAL == -1){
print "CHECK_FLOW: Error! check. Check the log file mem_check.log\n";
}
else{
print "CHECK_FLOW: Completed check.\n";
}
my $filename = 'check.log';
open(my $fh, '>', $filename);
print $fh "$output\n";
close $fh;
I inserted an error in the $tool_path purposely and used the debugger which shows the $EXITVAL to be 0 in both cases.
Is there anything I am missing? Is there any other way to accomplish what I am trying to do?
Upvotes: 0
Views: 132
Reputation: 386206
Contrary to your unsupported claims, it does work as documented.
use strict;
use warnings qw( all );
use IPC::System::Simple qw( capture EXIT_ANY $EXITVAL );
{
my $output = capture(EXIT_ANY, 'perl', '-e', 'print "abc\n"; exit(123);');
print("<$_>\n") for split /\n/, $output;
print("$EXITVAL\n");
}
print("--\n");
{
my $output = capture(EXIT_ANY, 'non-existent');
print("<$_>\n") for split /\n/, $output;
print("$EXITVAL\n");
}
Output:
<abc>
123
--
"non-existent" failed to start: "No such file or directory" at a.pl line 15.
Upvotes: 0
Reputation: 54333
You can use Capture::Tiny to do this. Your use-case is actually the first in the synopsis of the docs.
use strict;
use warnings;
use Capture::Tiny;
my ($stdout, $stderr, $exit) = capture {
system( './foo.pl', @args );
};
if ($exit) {
warn 'something went wrong when executing foo.pl';
}
Upvotes: 2