perl - 为什么本地在 STDERR 和 STDOUT 上不起作用?

标签 perl redirect stdout stderr

对于我即将推出的 PulseAudio 库,我想重定向 STDERRSTDOUT/dev/null从逻辑上讲,这是有效的,

sub _exec {
    open (*STDERR, '>', '/dev/null');    
    open (*STDOUT, '>', '/dev/null');    
    CORE::system('pacmd', @_ ) or die $?;

但是,这仍然输出到术语....
sub _exec {
    local ( *STDERR, *STDOUT );
    open (*STDERR, '>', '/dev/null');    
    open (*STDOUT, '>', '/dev/null');    
    CORE::system('pacmd', @_ ) or die $?;

这给我留下了两个问题
  • 首先,为什么我会经历我所看到的行为?
  • 其次,是否有更有效的方法不涉及存储旧值并替换它?
  • 最佳答案

    child 写入 fd 1 和 2,但您没有更改 fd 1 和 2。您只是使用 fd 3 和 4( child 不关心的东西)创建了新的 Perl 变量( child 一无所知)。

    这是实现您想要的一种方法:

    use IPC::Open3 qw( open3 );
    
    sub _exec {
        open(local *CHILD_STDIN,  '<', '/dev/null') or die $!;
        open(local *CHILD_STDOUT, '>', '/dev/null') or die $!;
        my $pid = open3(
            '<&CHILD_STDIN',
            '>&CHILD_STDOUT',
            undef,  # 2>&1
            'pacmd', @_,
        );
        waitpid($pid, 0);
        die $! if $? == -1;
        die &? if $?;
    }
    
    open3是相当低的水平,但它比自己做要高得多*。 IPC::RunIPC::Run3甚至更高的水平。



    * — 它负责 fork 并将句柄分配给正确的文件描述符。它处理错误检查,包括使 pre- exec子进程中的错误似乎是它们的启动失败,而不是来自已执行程序的错误。

    关于perl - 为什么本地在 STDERR 和 STDOUT 上不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13833088/

    相关文章:

    regex - 如何停止搜索单词(regex、grep)?

    stdout - 同时捕获和显示 STDOUT

    shell - 展示 bash shell stdout/stderr 重定向行为的备忘单

    javascript - js ecwid url重定向

    php - 使用 httpd 将 www.domain.com 和 domain.com 重定向到 subdomain.domain.com

    .htaccess - 301重定向到新页面保留查询字符串

    bash - 修改 "... | tee -a out.txt"以实时流式传输输出,而不是在完成时?

    perl - 如何将 UTF-8 字符串与 Perl 的 printf 正确对齐?

    mysql - 在 Perl 中使用 CSV_XS 和 DBI 编写 SQL 查询结果的问题

    Perl 模块 Capture::Tiny 捕获字符串变量中的代码