7

私の今後の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 $?;

それは私に2つの質問を残します

  1. 何よりもまず、私が見ている動作を経験しているのはなぜですか?
  2. 第二に、古い値を保存して置き換える必要のない、より効率的な方法はありますか?
4

1 に答える 1

9

子はfd1と2に書き込みますが、fd 1と2は変更しませんでした。fd3と4(子が気にしないもの)を使用して新しいPerl変数(子が何も知らないもの)を作成しただけです。

これがあなたが望むものを達成する一つの方法です:

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はさらに高いレベルです。



* —適切なファイル記述子へのハンドルのフォークと割り当てを処理します。子の事前execエラーを、実行されたプログラムからのエラーではなく、起動の失敗であるように見せることを含む、エラーチェックを処理します。

于 2012-12-12T05:43:16.617 に答える