Reputation: 13564
I am currently modifying a Perl script that executes several shell commands, and, for some of them, capture the output for further processing. I want to factor out the code that executes the external commands in subroutines. I wrote the following subroutines:
sub execute_command {
my $cmd = shift;
Log("executing command $cmd ...");
system($cmd);
my $app = ( $? == -1 ) ? $? : $? >> 8;
if ($app != 0) {
Log("error executing command $cmd");
return $FAILURE;
}
Log("done");
return $SUCCESS;
}
sub execute_command_and_get_output {
my $cmd = shift;
Log("executing command $cmd ...");
unless (open( CMD, "$cmd|" )) {
Log("error executing command $cmd");
return undef;
}
my @cmd = <CMD>;
close(CMD);
Log("done");
return @cmd;
}
Questions:
execute_command
should execute the passed command and return $SUCCESS
if everything is OK, or $FAILURE
in case of errors. Am I testing $?
in the right way?
execute_command_and_get_output
should execute the passed command and return the output as an array (containing the output lines); if the execution of the command fails, it should return undef
. Is it correct to use unless (open( CMD, "$cmd|" )) { ... }
to test for error conditions in the command execution?
Besides answers to my two questions, any suggestion for improvement is appreciated.
Upvotes: 0
Views: 313
Reputation: 2151
execute_command_and_get_output
can return two arguments:
$SUCCESS
or $FAILURE
execute_command
can also return two arguments:
$SUCCESS
or $FAILURE
An error message. For example:
system ($cmd) == 0 or return ($FAILURE,"error executing command $cmd: $!");
return ($SUCCESS, "done");
BTW, you can avoid going through the CMD
part using backticks (also, using the same name in more than one context is confusing).
my @lines = `$cmd`;
($? == 0) or return ($FAILURE,"error executing command $cmd: $!");
return ($SUCCESS, \@lines);
Upvotes: 1
Reputation: 9697
1) If you don't care what error has happened, it is enough to check return value of system
:
if(system($cmd) == 0) { return $SUCCESS } else { return $FAILURE }
2) Instead of return undef
, it is usually better to just return
. It works better when called in list context (it is still false). If the return is large, you might want to return reference to avoid copying.
Upvotes: 1