我目前正在修改执行多个shell命令的Perl脚本,对于其中一些命令,捕获输出以进行进一步处理。我想分解在子程序中执行外部命令的代码。我写了以下子程序:
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;
}
问题:
execute_command
应执行传递的命令,如果一切正常,则返回$SUCCESS
,如果出现错误,则返回$FAILURE
。我是否以正确的方式测试$?
?
execute_command_and_get_output
应执行传递的命令并将输出作为数组返回(包含输出行);如果命令执行失败,则应返回undef
。使用unless (open( CMD, "$cmd|" )) { ... }
在命令执行中测试错误条件是否正确?
除了我的两个问题的答案之外,任何改进的建议都表示赞赏。
答案 0 :(得分:1)
1)如果您不关心发生了什么错误,只需检查system
的返回值:
if(system($cmd) == 0) { return $SUCCESS } else { return $FAILURE }
2)仅return undef
代替return
而不是{{1}}。在列表上下文中调用它时效果更好(它仍然是错误的)。如果返回值很大,您可能希望返回引用以避免复制。
答案 1 :(得分:1)
execute_command_and_get_output
可以返回两个参数:
$SUCCESS
或$FAILURE
execute_command
也可以返回两个参数:
$SUCCESS
或$FAILURE
错误消息。例如:
system ($cmd) == 0 or return ($FAILURE,"error executing command $cmd: $!");
return ($SUCCESS, "done");
顺便说一下,你可以避免使用反引号通过CMD
部分(同样,在多个上下文中使用相同的名称会令人困惑)。
my @lines = `$cmd`;
($? == 0) or return ($FAILURE,"error executing command $cmd: $!");
return ($SUCCESS, \@lines);