首页 文章

perl合并输出和windows中的stderr和过滤行

提问于
浏览
2

我想在perl中运行一个外部命令并过滤一些行 . 我不知道如何过滤去stderr的行 . 我现在有以下代码:

#!/usr/bin/env perl

use File::Spec;
#open STDERR, '>', File::Spec->devnull() or die "could not open STDERR: $!\n";

open(FILEHANDLE, '-|', 'Mycmd') or die "Cannot fork: $!\n";
open(STDERR, ">&FILEHANDLE");

while(defined(my $line = <FILEHANDLE>)) {
  chomp($line);
  if( $line =~ m/text1/ or
    $line =~ m/text2/ or
    $line =~ m/text3/
  ) {
    # do nothing
  }
  else {
    print "$line\n";
  }
}
close FILEHANDLE or die "child error: $!\n";

这条线

open(STDERR, ">&FILEHANDLE");

是我尝试重定向stderr以便能够使用stdout处理它,但它不起作用 .

解决方案必须在Windows中工作 .

1 回答

  • 3

    参数中的shell重定向到 open 可以在这里帮助:

    open(FILEHANDLE, 'Mycmd 2>&1 |') or die "Cannot fork: $!\n";
    

    现在 FILEHANDLE 将从 Mycmd 看到标准输出和标准错误的每一行 .

    要使用多参数 open 和重定向输出,您必须更加慎重 . 说 Mycmd

    #! /usr/bin/env perl
    print "standard output\n";
    warn  "standard error\n";
    

    打开 "-|" 只给我们标准输出,所以如果我们运行

    #! /usr/bin/env perl
    
    use strict;
    use warnings;
    
    use 5.10.0;
    
    my $pid = open my $fh, "-|", "Mycmd" // die "$0: fork: $!";
    
    while (defined(my $line = <$fh>)) {
      chomp $line;
      print "got [$line]\n";
    }
    

    输出是

    standard error
    got [standard output]
    

    请注意, Mycmd 的标准输出通过驱动程序但不是标准错误 . 要获得两者,您必须模仿shell的重定向 .

    #! /usr/bin/env perl
    
    use strict;
    use warnings;
    
    use 5.10.0;
    
    my $pid = open my $fh, "-|" // die "$0: fork: $!";
    
    if ($pid == 0) {
      open STDERR, ">&STDOUT" or die "$0: dup: $!";
      exec "Mycmd"            or die "$0: exec: $!";
    }
    
    while (defined(my $line = <$fh>)) {
      chomp $line;
      print "got [$line]\n";
    }
    

    现在输出是

    got [standard error]
    got [standard output]
    

相关问题