简体   繁体   English

我怎样才能摆脱 Perl 中的 STDERR

[英]How can I get rid of the STDERR in Perl

I'm using some system commands in Perl.我在 Perl 中使用一些系统命令。

In the below case I was getting output as follows:在下面的例子中,我得到 output 如下:

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

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

No specified files found for deletion

My code:我的代码:

sub monthoryear() 
{

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

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

}

I don't want to see the following in the output even if there are no files.我不想在output中看到下面的内容,即使没有文件。

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

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

While the other answers are correct about the exact technical question you asked, you should also consider not writing what is effectively a shell script in Perl. 尽管其他答案对于您提出的确切技术问题是正确的,但您也应该考虑不要在Perl中编写有效的shell脚本。

You should use Perl native methods of getting file list (eg glob() or File::Find ) instead of calling a backticked ls . 您应该使用Perl本机方法来获取文件列表(例如glob()File::Find ),而不要调用反引号ls

Redirect STDERR to the null device: 将STDERR重定向到空设备:

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

You can add stderr redirection in your subshell commands: 您可以在子shell命令中添加stderr重定向:

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

Check out perlfaq8 . 查看perlfaq8 If you don't care if it's STDOUT or STDERR , you can get both redirected to STDOUT . 如果您不在意它是STDOUT还是STDERR ,则可以将它们都重定向到STDOUT

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

In your case, you probably just want to get rid of STDERR : 就您而言,您可能只想摆脱STDERR

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

However, I agree with DVK's answer . 但是,我同意DVK的回答 Using an external command to get a list of files just seems silly. 使用外部命令获取文件列表似乎很愚蠢。 You should use File::Find . 您应该使用File :: Find This way you can use Perl's normal error handling in case something fails. 这样,万一发生故障,您可以使用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";

Create a new warn hook, then do something with the message, store it, ignore it etc... 创建一个新的警告挂钩,然后对消息进行处理,存储,忽略它,等等。

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

You can redirect the stderr to /dev/null as: 您可以通过以下方式将stderr重定向到/dev/null

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

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

Subshells will inherit the parent's STDERR, so if you want to do it on a global level, you can do this: 子外壳程序将继承父级的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`;

Often you also want to restore STDERR later.通常您还想稍后恢复STDERR I do this like this:我这样做:

#!/usr/bin/perl

print STDERR "This will be send to the old (readable) STDERR\n";

my $oldstderr = readlink "/proc/self/fd/2"; #Remember the location of the old STDERR
open(STDERR, ">/dev/null"); #Ignore STDERR now

print STDERR "This will be send to a STDERR that is 'gone'\n";

open(STDERR, ">$oldstderr"); #restores STDERR to the old state

print STDERR "This will be send to the old (readable) STDERR again\n";

OR或者

You can use the Capture::Tiny module which makes it easier to read and more portable.您可以使用Capture::Tiny模块,它更易于阅读和便携。

#!/usr/bin/perl
use Capture::Tiny qw/capture_stderr/;

print STDERR "This will be send to the old (readable) STDERR\n";
capture_stderr sub {
  print STDERR "This will be send to a STDERR that is 'gone'\n";
};
print STDERR "This will be send to the old (readable) STDERR again\n";

Here's how you can suppress STDERR, capture error messages that occur while turned off, restore STDERR, and report back any captured error messages.下面介绍了如何抑制 STDERR、捕获关闭时出现的错误消息、恢复 STDERR 以及报告任何捕获的错误消息。

#!/usr/bin/perl
use warnings;
use strict;

print STDERR "STDERR is on.\n";
my ($stderr_fh, $err_msg_ref) = suppress_std_err();
print "STDERR is now off and error messages are being suppressed and saved.\n";
print STDERR "I'm an error message.\n";
restore_std_err($stderr_fh);
print STDERR "STDERR is back on\n";
print "Errors reported while STDERR was off: $$err_msg_ref\n";

#Saves STDERR in filehandle then turns it off.
#Any error messages that occur while STDERR is off are stored for safekeeping.
sub suppress_std_err {
        my $suppressed_std_error_messages;
        open (my $saved_std_err_fh, ">&", STDERR);
        close STDERR;
        open (STDERR, ">", \$suppressed_std_error_messages);
        return ($saved_std_err_fh, \$suppressed_std_error_messages);
}

#Restores STDERR from saved filehandle.
sub restore_std_err {
        my $old_std_err_fh = shift;
        close STDERR;
        open (STDERR, ">&", $old_std_err_fh);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Perl中打开()和关闭()STDERR? - How can I open() and close() STDERR in Perl? 如何在Perl中通过SSH获取在远程机器上执行的命令的STDERR和STDOUT? - How can I get STDERR and STDOUT of a command executed on a remote machine through SSH in Perl? 如何在Log4perl中抑制输出到stdout和stderr? - How can I suppress output to stdout and stderr in Log4perl? 如何重新初始化Perl的STDIN / STDOUT / STDERR? - How can I reinitialize Perl's STDIN/STDOUT/STDERR? 在Perl中命令执行失败时如何读取stderr? - How can I read stderr when a command execution fails in Perl? 如何在Perl中向STDERR输出添加时间信息? - How can I add time information to STDERR output in Perl? 我怎样才能摆脱 ubuntu 14.04 桌面中的“apache2 : Depends: perl but it is not going to be installed”? - How can i get rid of "apache2 : Depends: perl but it is not going to be installed" in ubuntu 14.04 desktop? 我怎样才能摆脱 Perl 的 Pod 的空行,这样它们就不会出现在 Pod::Usage 中? - How can I get rid of empty lines Perl's Pod so they don't show up with Pod::Usage? eclipse 中的 Perl EPIC:尝试运行 Z0114AD4E 脚本36D72395EF18A 时,如何摆脱此 Ant 构建对话框? - Perl EPIC in eclipse: How do I get rid of this Ant Build dialog when trying to run a Perl script? 如何摆脱Perl中数组中的空字符串? - How to get rid of the empty string in the array in perl?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM