gpt4 book ai didi

perl - 在 Perl 中抑制/捕获/捕获失败的 fork open() 错误消息

转载 作者:行者123 更新时间:2023-12-03 07:55:38 25 4
gpt4 key购买 nike

考虑:

#!/usr/bin/perl

use strict;
use warnings;

my $command = "nosuchcommand"

my $rc = open( my $fh, "-|", "$command" );

if ( ! defined( $rc ) )
{
print "My own error message\n";
}
else
{
system( "ps -p $rc" );
}

预期输出:

My own error message

观察到的输出:

Can't exec "nosuchcommand": No such file or directory at ./mcre line 8.
My own error message

如何捕获/捕获/抑制 Perl 在失败的开放管道上生成的错误消息(有利于我自己的错误处理)?

进一步观察:

  • 如果我 open( my $fh, "-|", "$command 2>&1");,我会得到预期的输出。但是如果$command成功,我会将$commandSTDERR混合到中STDOUT,我不想要这样。

  • 如果我 open( my $fh, "-|", "$command 2>/dev/null");,我会得到:

    PID TTY          TIME CMD
15143 pts/0 00:00:00 sh <defunct>

因此,2>/dev/null(而不是2>&1)的特定重定向更改了的返回值open...这有点令人惊讶,但不是我问题的核心。

在 IPC::Run

到目前为止,这已在两个答案中提出。我知道在一般情况下这可能是“正确”的答案,但真的不愿意(因为IPC::Run对我来说不是一个选项非常重要的目标平台,没有它并且不提供简单的安装方法)。

最佳答案

该消息不是来自 Perl,而是来自您启动以执行 shell 命令的 shell。[1] 这是因为

open( my $fh, "-|", $shell_command )

相当于

open( my $fh, "-|", "/bin/sh", "-c", $shell_command )

正如您所建议的,您可以使用 2>/dev/null 重定向 STDERR,但这也会消除程序中的错误(当使用有效程序时)。

您可以执行以下操作:

use IPC::Run qw( run );

my @cmd = ( $prog, @args );

eval { run \@cmd };
if ( $@ ) {
die( "Problem creating child: $@" );
}
elsif ( $? & 0x7F ) {
die( "Child died from signal ".( $? & 0x7F )."\n" );
}
elsif ( $? >> 8 ) {
die( "Child exited with error ".( $? >> 8 )."\n" );
}

如果您想要更多的控制权,您需要自己实现。 IPC::Open3 的 open3 源代码将是一个好的开始。


  1. 除了 Perl 针对简单的 shell 命令优化了 shell 的使用之外,因此该消息实际上来自 Perl。但这在这里并不是一个有用的区别。

关于perl - 在 Perl 中抑制/捕获/捕获失败的 fork open() 错误消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76092519/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com