2010-02-13 2 views
3

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

Моя система 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('[email protected]_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(); 

ответ

6

Возможно, вы недостаточно терпеливы? Я вижу, что скрипт ждет 3 минуты до выхода.

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

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

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

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

$log->autoflush(1); # untested 

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

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

+0

Я думаю, вы имеете в виду, что он ждет 30 минут. 60 * 30. – Geo

+0

Спасибо :), то есть решение – XoR

1

пытаются сделать это просто первый

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

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

+0

да, это так. Это была проблема с промывкой буферов. Я не выбрал дескриптор файла перед установкой $ | переменная. – XoR

2

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

7

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

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 минут от хрон. Таким образом, вы избавитесь от цикла:

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

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

.... do error stuff here ... 
Смежные вопросы