我想在 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 中运行。
最佳答案
参数中的 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]
Notice that the standard output from Mycmd
passed through the driver program but not its standard error. To get both, you have to mimic the shell’s redirection.
#! /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]
关于Perl 合并输出和 stderr 以及 Windows 中的过滤行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10585120/