我怎样才能摆脱 Perl 中的 STDERR

发布于 2024-10-19 09:27:25 字数 532 浏览 4 评论 0原文

我正在 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

I'm using some system commands in Perl.

In the below case I was getting output as follows:

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.

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

二货你真萌 2024-10-26 09:27:25

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

您应该使用 Perl 本机方法来获取文件列表(例如 glob()File::Find),而不是调用反引号的 ls

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.

You should use Perl native methods of getting file list (e.g. glob() or File::Find) instead of calling a backticked ls.

过潦 2024-10-26 09:27:25

将 STDERR 重定向到空设备:

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

Redirect STDERR to the null device:

use File::Spec;
open STDERR, '>', File::Spec->devnull() or die "could not open STDERR: $!\n";
记忆消瘦 2024-10-26 09:27:25

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

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

You can add stderr redirection in your subshell commands:

@importlog = `ls -al import-log.* 2>/dev/null`;
@errorlog = `ls -al error-log.* 2>/dev/null`;
北风几吹夏 2024-10-26 09:27:25

查看 perlfaq8< /a>.如果您不关心它是 STDOUT 还是 STDERR,则可以将两者都重定向到 STDOUT

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

就您而言,您可能只想摆脱 STDERR

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

但是,我同意 DVK 的回答。使用外部命令来获取文件列表似乎很愚蠢。您应该使用 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";

Check out perlfaq8. If you don't care if it's STDOUT or STDERR, you can get both redirected to STDOUT.

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

In your case, you probably just want to get rid of STDERR:

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

However, I agree with DVK's answer. Using an external command to get a list of files just seems silly. You should use File::Find. This way you can use Perl's normal error handling in case something fails.

#!/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";
鸠魁 2024-10-26 09:27:25

创建一个新的警告挂钩,然后对消息执行某些操作,存储它,忽略它等等......

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

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;
};
阳光①夏 2024-10-26 09:27:25

您可以将 stderr 重定向到 /dev/null,如下所示:

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

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

You can redirect the stderr to /dev/null as:

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

@errorlog = `ls -al error-log.* 2> /dev/null`;
迷爱 2024-10-26 09:27:25

子 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`;

Subshells will inherit the parent's STDERR, so if you want to do it on a global level, you can do this:

open(STDERR,'>/dev/null');
`ls non-existent-file`;
`ls non-existent-file2`;
`ls non-existent-file3`;
`ls non-existent-file4`;
`ls non-existent-file5`;
伤痕我心 2024-10-26 09:27:25

通常您还想稍后恢复STDERR。我这样做是这样的:

#!/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

您可以使用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";

Often you also want to restore STDERR later. 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.

#!/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";
财迷小姐 2024-10-26 09:27:25

以下是如何抑制 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);
}

Here's how you can suppress STDERR, capture error messages that occur while turned off, restore STDERR, and report back any captured error messages.

#!/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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文