Почему моя программа Perl ничего не выводит в мой файл? - PullRequest
3 голосов
/ 13 февраля 2010

Я пытаюсь записать в файл ~ / .log , но файл остается пустым. Я не знаю, почему это происходит, все вроде нормально.

Моя система 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 = ('mejl1@provider1.com',
        'mejl2@provider2.com',
        );
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();

Ответы [ 4 ]

7 голосов
/ 13 февраля 2010

Вам нужно отлаживать каждый шаг вашего скрипта. У вас есть:

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

Хотя вы, вероятно, изменили URL своего вопроса, как написано get, вероятно, возвращает undef. Я не уверен, почему вы используете until там. Вы хотите запустить это навсегда, пока сайт не станет онлайн? Проверьте возвращаемые значения всего, чтобы увидеть, что происходит.

Я бы сократил большую часть этой части вашего сценария до простого:

 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 ...
      }

Однако вместо 30 минут сна просто запускайте скрипт каждые 30 минут из cron. Таким образом, вы избавляетесь от циклов:

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

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

 .... do error stuff here ...
6 голосов
/ 13 февраля 2010

Может быть, вы недостаточно терпеливы? Я вижу, что сценарий ждет 3 минуты, прежде чем выйти.

Обратите внимание, что $| работает только для выбранного в настоящий момент дескриптора файла , что означает STDOUT здесь.

Вы можете установить его для любого дескриптора файла в старой школе, сложным способом:

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

или, если ваш файловый дескриптор происходит от определенного класса - и, возможно, автовивифицированные дескрипторы принадлежат этому классу - тогда вы можете использовать метод autoflush, который намного проще для вас, но делает то же вещь под капотом:

$log->autoflush(1);   # untested

Будем надеяться, что последний работает.

См. IO :: Handle и FileHandle для autoflush - они связаны, но я не уверен, что здесь применимо.

2 голосов
/ 13 февраля 2010

Код, который вы предоставляете, записывается только в файлы журнала, если что-то идет не так или если $ match_string находится в $ content. Может ли быть так, что все работает нормально, но нет совпадения, поэтому пустой файл журнала - это именно то, чего вы должны ожидать?

1 голос
/ 13 февраля 2010

попробуйте сначала упростить

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

это работает?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...