2011-09-20 102 views
0

我目前正在修改一个执行多个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;  
} 

问题:

  1. execute_command应该在错误的情况下执行该命令传递和返回$SUCCESS如果一切正常,或$FAILURE。我是否正确测试$?

  2. execute_command_and_get_output应执行传递的命令并将输出作为数组返回(包含输出行);如果命令的执行失败,则应返回undef。使用unless (open(CMD, "$cmd|")) { ... }来测试命令执行中的错误条件是否正确?

除了我的两个问题的答案,任何改善建议表示赞赏。

回答

1

1)如果你不关心发生了什么错误,就足以检查system返回值:

if(system($cmd) == 0) { return $SUCCESS } else { return $FAILURE } 

2)替代return undef,它通常是最好只return。它在列表环境中调用时效果更好(它仍然是false)。如果回报很大,则可能需要返回引用以避免复制。

1
  • execute_command_and_get_output可以返回两个参数:

    1. $SUCCESS$FAILURE
    2. 的引用数组,要么具有结果或空
  • execute_command也可以返回两个参数:

    1. $SUCCESS$FAILURE
    2. 错误消息。例如:

      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); 
    
+0

感谢您的回答:我很欣赏的想法,但是我更喜欢从'execute_command_and_get_output'返回多个值,我也不行多使用反引号的。 – MarcoS

相关问题