Search code examples
perldaemon

Why won't my perl daemon print?


I am debugging a daemon and I'm trying to use print statements to output information to the terminal. The gist of my code is:

#!/usr/bin/env perl

use strict;
use warnings;

use Readonly;

Readonly my $TIMEOUT => ...;

...

while (1) {

   print "DEBUG INFO";

   ...

   sleep $TIMEOUT;
}

However, no output it getting printed to my terminal. Why is this?


Solution

  • Summary:

    Use $| = 1 or add a newline, "\n" to the print.

    Explanation:

    The reason this isn't printing to the terminal is because perl is buffering the output for efficiency. Once the print buffer has been filled it will be flushed and the output will appear in your terminal. It may be desirable for you to force flushing the buffer, as depending on the length of $TIMEOUT you could be waiting for a considerable length of time for output!

    There are two main approaches to flushing the buffer:

    1) As you're printing to your terminal, then your filehandle is most likely STDOUT. Any file handles attached to the terminal are by default in line-buffered mode, and we can flush the buffer and force output by adding a newline character to your print statement:

    while (1) {
        print "DEBUG INFO\n";
        ...
        sleep $TIMEOUT;
     }
    

    2) The second approach is to use $| which when set to non-zero makes the current filehandle (STDOUT by default or the last to be selected) hot and forces a flush of the buffer immediately. Therefore, the following will also force printing of the debug information:

    $| = 1;
    while (1) {
        print "DEBUG INFO";
        ...
        sleep $TIMEOUT;
    }
    

    If using syntax such as this is confusing, then you may like to consider:

    use IO::Handle;
    STDOUT->autoflush(1);
    
    while (1) {
        print "DEBUG INFO";
        ...
        sleep $TIMEOUT;
    }
    

    In many code examples where immediate flushing of the buffer is required, you may see $|++ used to make a file-handle hot and immediately flush the buffer, and --$| to make a file-handle cold and switch off auto-flushing. See these two answers for more details:

    If you're interested in learning more about perl buffers, then I would suggest reading Suffering from Buffering, which gives great insight into why we have buffering and explains how to switch it on and off.