Q: Why Perl warn() or other STDERR output is not shown/logged/saved/flushed into my log file?
A: You may have encountered the well-known feature of stream buffering which is enabled by default.
An excerpt from the perlvar documentation says that “…STDOUT will typically be line buffered if output is to the terminal and block buffered otherwise”. Thus it is always buffered, also for STDERR.
Usually people remember to set STDOUT as auto-flush, but you should enable this for STDERR as well, or else your messages to STDERR may not appear in your log file immediately, if you are redirecting STDERR to a file.
The following piece of code sets an auto-flush for both STDOUT and STDERR:
select(STDERR); $| = 1; select(STDOUT); # default $| = 1;
The select() function and the $| variable are built-in for Perl and require no additional libraries to be included.
Alternatively, you can also use IO::Handle to achieve the same result:
use IO::Handle; STDERR->autoflush(1); STDOUT->autoflush(1);
I never realized why stream buffering for both STDOUT and STDERR is enabled by default for most scripting languages… But that’s just me.
References:
- Flushing Output
- search Google for “perl flush stdout” or “perl flush output” or just “perl flush“