我怎样才能摆脱Perl中的STDERR

时间:2011-02-25 17:30:06

标签: perl redirect stderr system-calls

我在Perl中使用了一些系统命令。

在下面的例子中,我得到的输出如下:

ls: import-log.*: No such file or directory

ls: error-log.*: No such file or directory

No specified files found for deletion

我的代码:

sub monthoryear() 
{

  @importlog = `ls -al import-log.*`;

  @errorlog = `ls -al error-log.*`;

}

即使没有文件,我也不希望在输出中看到以下内容。

ls: import-log.*: No such file or directory &

ls: error-log.*: No such file or directory

7 个答案:

答案 0 :(得分:14)

虽然其他答案对于您提出的确切技术问题是正确的,但您还应该考虑不在Perl中编写有效的shell脚本。

您应该使用Perl原生方法来获取文件列表(例如glob()File::Find),而不是调用回退的ls

答案 1 :(得分:6)

将STDERR重定向到空设备:

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

答案 2 :(得分:5)

您可以在子shell命令中添加stderr重定向:

@importlog = `ls -al import-log.* 2>/dev/null`;
@errorlog = `ls -al error-log.* 2>/dev/null`;

答案 3 :(得分:4)

结帐perlfaq8。如果您不在乎STDOUTSTDERR,则可以将其重定向到STDOUT

$output = `$cmd 2>&1`;

在您的情况下,您可能只想摆脱STDERR

$output = `$cmd 2>/dev/null`;

但是,我同意DVK's answer。使用外部命令获取文件列表似乎很愚蠢。您应该使用File::Find。通过这种方式,您可以使用Perl的正常错误处理,以防出现故障。

#!/usr/bin/perl
use strict;
use warnings;
use File::Find;

my @importlog;
my @errorlog;
find(sub {
    push @importlog, $File::Find::name if /^import-log\.*/;
    push @errorlog, $File::Find::name if /^error-log\.*/;
}, '.');

print "Import log:\n", join("\n", @importlog), "\n";
print "Error log:\n", join("\n", @errorlog), "\n";

答案 4 :(得分:2)

创建一个新的警告钩子,然后对消息做一些事情,存储它,忽略它等等......

local $SIG{__WARN__} = sub {
  my $message = shift;

  ## do nothing to ignore all together

  ## ignore specific message
  # warn $message unless $message =~ /No such file or directory/;

  ## or do something else
  # die $message ## make fatal
  # open my $fh, '>', 'file.log'; print $fh $message;
};

答案 5 :(得分:1)

您可以将stderr重定向到/dev/null

@importlog = `ls -al import-log.* 2> /dev/null`;

@errorlog = `ls -al error-log.* 2> /dev/null`;

答案 6 :(得分:0)

子shell将继承父级的STDERR,因此如果你想在全局级别上执行,你可以这样做:

open(STDERR,'>/dev/null');
`ls non-existent-file`;
`ls non-existent-file2`;
`ls non-existent-file3`;
`ls non-existent-file4`;
`ls non-existent-file5`;