Reputation: 50667
How does warn 4
differ from print STDERR 4
?
perl -e 'local *STDERR; warn 4'
(output still goes to STDERR
)
perl -e 'local *STDERR; print STDERR 4'
(no output here)
Upvotes: 4
Views: 469
Reputation: 386646
warn
triggers $SIG{__WARN__}
.warn
doesn't use $\
or $,
.warn
apparently uses the file handle in the original STDERR
, as you've demonstrated[1].Not quite. Your code could also demonstrate that warn
uses fd 2 directly, but that's disproven by
close(STDOUT);
close(STDERR);
open(STDERR, '>file');
warn(fileno(STDERR)."abc"); # 1abc
Upvotes: 6
Reputation: 150
local
here only says that the typeglob STDERR
is local from this point on, it doesn't change anything with STDERR handle already seen by sig warn default handler by the time you enter this block. You need to reopen the handle to something else if you want to really silence STDERR.
If you want to silence it locally and then restore, here's how to do it, if you really must insist to resort to low-level globs and handles:
#!/usr/bin/perl -w
sub f() {
local *STDERR;
open STDERR, '>/dev/null';
warn 4;
}
warn 3;
f();
warn 5;
Upvotes: 2
Reputation: 123648
You haven't silenced the STDERR
handle yet. In order to really silence it, you need to say:
perl -e 'local *STDERR; open(STDERR, ">/dev/null") or die $!; warn 4'
perldoc perlvar
tells:
As the
'IGNORE'
hook is not supported by__WARN__
, you can disable warnings using the empty subroutine:local $SIG{__WARN__} = sub {};
Upvotes: 4