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

对于我即将推出的 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 $?;

这留给我两个问题

  1. 首先,也是最重要的,为什么我会遇到我所看到的行为?
  2. 其次,有没有更高效的方法,不涉及存储旧值并替换它?

最佳答案

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::Run和 IPC::Run3甚至更高。



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

https://stackoverflow.com/questions/63282296/

相关文章:

php - 在 Laravel 中通过表格获得一行的最佳方法是什么?

reactjs - EsLint 错误解释 no-unused-vars 中的导入语句

image - 在 vim 文件中插入 bash 脚本输出

c# - EpiServer DynamicDataStore LINQ 语句中的 sql 语法不正

node.js - cors 问题与 passport.js google oauth 策略

azure - 如何在函数应用中为Azure SignalR服务使用不同的连接字符串?

text - 关注 VStack 中的下一个 TextField

python - 当某些列值为空时,如何合并 Dataframe 中的多行?

angular - 如何更新 Angular 中提供者提供的值?

caching - Mike Acton 的面向数据设计 - 'loops per cache li