【问题标题】:perl merge output and stderr and filter lines in windowsperl 在 windows 中合并输出和 stderr 和过滤行
【发布时间】:2012-05-14 23:36:31
【问题描述】:

我想在 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 中运行。

【问题讨论】:

  • 你先关闭STDERR了吗?我认为您无法打开已经打开的FH

标签: perl


【解决方案1】:

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

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";
}

输出是

标准错误
得到[标准输出]

注意来自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";
}

现在输出是

得到[标准错误]
得到[标准输出]

【讨论】:

  • 谢谢,我不知道这种重定向也可以在windows中使用,我对bash中的那些很熟悉。
  • @skeept 不客气!我很高兴它有帮助,并查看自己执行重定向的更新答案,这样您就可以绕过 shell 的愚蠢参数解析。
猜你喜欢
  • 2011-08-20
  • 1970-01-01
  • 1970-01-01
  • 2014-05-14
  • 1970-01-01
  • 2012-10-26
  • 1970-01-01
  • 2023-04-06
  • 2016-03-19
相关资源
最近更新 更多