需要输出system()命令的动作并具有进度指示器

时间:2011-06-17 21:02:06

标签: perl pipe progress-indicator

我有一个很好的进度指标来自Need a progress indicator for a Perl system() command using T:R:G mod

open(my $cmd, '-|', "$command $flags_args 2>/dev/null")
  or print "\nAttention: Command $command $flags_args failed $!"
  and return 1;

while (<$cmd>)
{
  $percentage = ($cntr/$lines) * 100;
  $percentage = 100 if $percentage > 100;

  printf("Progress: %3d%%\r", $percentage);
  $cntr++;

}
close($cmd);

现在我想要记录命令输出的STDOUT和STDERR。我对管道输出不太熟悉所以我尝试添加:

print $LOG $cmd

print $LOG Dumper(\$cmd)
在while循环结束之前

。那没起效。第一个输出

GLOB(0x11df7a0)GLOB(0x11df7a0)GLOB(0x11df7a0)

第二个

$VAR1 = \\*{'::$cmd'};
$VAR1 = \\*{'::$cmd'};
$VAR1 = \\*{'::$cmd'};

有谁知道如何从管道$ cmd获取输出? $ command = make命令的示例

 Making all in src
 make[1]: Entering directory `/tmp' 
 Making all in include
 make[2]: Entering directory '/tmp/2'

 ...

2 个答案:

答案 0 :(得分:4)

尝试制作

 print $LOG $_;

或者只是

 print $LOG;

(因为如果没有指定任何内容,$_是默认值)

解释:$cmd是您正在阅读的文件; $_是从中读取的行。您可以通过写下来更清楚:

 while ($line = <$cmd>) {
    print $LOG $line;
    ...
 }

答案 1 :(得分:2)

$cmd是命令输出的I / O句柄,这是一种内部数据类型,打印时没有多大意义。您希望使用<$cmd>readline($cmd)来获取它的输出,您已在while循环中执行此操作:

while (<$cmd>)      # same as:    while (defined($_ = readline($cmd)))
{
  # last line from command is now stored in $_
  print $LOG $_;

  $percentage = ($cntr/$lines) * 100;
  $percentage = 100 if $percentage > 100;

  printf("Progress: %3d%%\r", $percentage);
  $cntr++;


}