For my upcoming PulseAudio library I want to redirect STDERR
and STDOUT
to /dev/null
logically this works,
sub _exec {
open (*STDERR, '>', '/dev/null');
open (*STDOUT, '>', '/dev/null');
CORE::system('pacmd', @_ ) or die $?;
However, this still outputs to the term....
sub _exec {
local ( *STDERR, *STDOUT );
open (*STDERR, '>', '/dev/null');
open (*STDOUT, '>', '/dev/null');
CORE::system('pacmd', @_ ) or die $?;
That leaves me with two questions
The child writes to fd 1 and 2, yet you didn't change fd 1 and 2. You just created new Perl variables (something the child knows nothing about) with fd 3 and 4 (something the child doesn't care about).
Here's one way of achieving what you want:
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
is pretty low level, but it's far higher level than doing it yourself*. IPC::Run and IPC::Run3 are even higher level.
* — It takes care for forking and assigning the handles to the right file descriptors. It handles error checking, including making pre-exec
errors in the child appear to be the launch failures they are and not errors from the executed program.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With