Search code examples
perllwp

Why doesn't my Perl program output anything to my file?


I'm trying to write in file ~/.log but file is remaining empty. I don't know why this is happening, everything seems fine.

My system is Ubuntu 9.10amd64, Perl 5.10.

#!/usr/bin/perl
# vim:set filetype=perl:

use strict;
use warnings;

use LWP::Simple qw||;
use Net::SMTP;

# Only because log file
$| = 1;

my $match_string = "... some text to match ..." ;
my $content;

my @mails = ('[email protected]',
        '[email protected]',
        );
my $data = <<END;

... Subject text ...

END

open(my $log, ">>","$ENV{HOME}/.log")
or die "Couldn't open log file";

sub get( $ ) {
    my $content_ref = shift;

    print {$log} "get: Error: $!\n"
        until ( ${$content_ref}
                = LWP::Simple::get("www.somesite.com/index.html") );
}


my $check_num = 0;
get( \$content );
while ( index($content, $match_string) != -1) {
    print {$log} "Check number $check_num\n"
        or die "Couldn't write in log file";
# This is printed
#    print "Check number $check_num: $ENV{HOME}/.log\n";
    $check_num++;
    get( \$content );
    sleep 60*30;
}


my $server = "smtp.my_provider.org";
my $smtp = Net::SMTP->new($server)
    or print {$log} "smtp: Couldn't connect on $server\n";

$smtp->mail('my_mail@my_provider.org')
    or print {$log} "smtp: Error in mail\n";
$smtp->bcc(@mails)
    or print {$log} "smtp: Error in bcc\n";

$smtp->data();

$smtp->datasend($data)
    or print {$log} "smtp: Error when sending data\n";
$smtp->dataend;

$smtp->quit();

Solution

  • Maybe you're not patient enough? I see the script waits 3 minutes before exiting.

    Note that $| works only for the currently selected filehandle, which means STDOUT here.

    You can set it for any filehandle in the old school, complex way:

    {
        my $old = select $log;
        $| = 1;
        select $old;
    }
    

    or, if your filehandle is descending from a particular class -- and it's possible autovivified handles belong to this class -- then you can use the autoflush method instead, which is a lot easier for you, but does the same thing under the hood:

    $log->autoflush(1);   # untested
    

    Let's hope the latter works.

    See IO::Handle and FileHandle for autoflush -- they're related, but I'm unsure which applies here.