tags:

views:

121

answers:

4

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();
+5  A: 

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.

bart
I think you mean it waits 30 minutes. 60*30.
Geo
Thanks :), that is the solution
XoR
+1  A: 

try to make it simple first

open(my $log, ">>","~/.log")
or die "Couldn't open log file";
print $log "smtp: Error in mail\n";
close  $log 

does this works ?

jojo
yes, it does. It was just the problem with flushing the buffers. I didn't selected the file handle before setting $| variable.
XoR
+2  A: 

The code you present only writes to the log files if anything goes wrong or if $match_string is in $content. Could it be that everything is working fine but there is no match, so the empty log file is exactly what you should be expecting?

Leon Timmermans
+5  A: 

You need to debug each step of your script. You have:

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

Although you probably changed the URL for your question, as written get is probably returning undef. I'm not sure why you are using until there. Do you want to run that forever until a site comes online? Check the return values of everything to see what's going on.

I'd reduce most of that part of your script to simply:

 while( 1 ) {
      my $data = LWP::Simple::get("http://www.somesite.com/index.html");
      print "got [$data]\n";

      if( substr( ... ) > -1 ) { sleep 1800; next }

      .... do error stuff here ...
      }

However, instead of sleeping for 30 minutes, just run the script every 30 minutes from cron. That way you get rid of the looping:

 my $data = LWP::Simple::get("http://www.somesite.com/index.html");
 print "got [$data]\n";

 exit if( substr( ... ) > -1 );

 .... do error stuff here ...
brian d foy