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
- First and foremost, why am I experiencing the behavior that I’m seeing?
- Secondly, is there a more efficient method that doesn’t involve storing the old value and replacing it?
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:
open3is 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-
execerrors in the child appear to be the launch failures they are and not errors from the executed program.