Сбой сценария Perl в crontab - PullRequest
       6

Сбой сценария Perl в crontab

0 голосов
/ 25 ноября 2011

У меня есть Perl-скрипт, который читает наши журналы доступа к брандмауэру, чтобы узнать, кто использовал конкретную учетную запись vpn.Это прекрасно работает при запуске из командной строки, но не работает при запуске из crontab.Код здесь

#!/usr/bin/perl -w
use strict;
use warnings;
use MIME::Lite::TT::HTML;
my $basedir = "/var/log";
my @verdir = qw(fw_d);
my $fulldir;
my $configs; 
my $combidir;
my @results;
my @files1;
foreach $combidir (@verdir) {
    $fulldir = "$basedir/$combidir";
    opendir (DIR, $fulldir);
    my @files = grep { $_ ne '.' && $_ ne '..' && $_ ne 'CVS' } readdir DIR;
    closedir (DIR);
    @files1 = sort {expand($a)cmp expand($b)}(@files);
    foreach my $configs (@files1) {
        my $now = time;
        my @stat = stat("$fulldir/$configs");
        if ($stat[9] > ($now - 2592000)) {
            system("/usr/bin/less -f $fulldir/$configs | /bin/grep NETOPS_TUNNEL >> /usr/local/CCS/ravpn/output.log"); }
        }
    }
    results();
    sendmailnew(\@results);

    sub results{
        my $input = "/usr/local/CCS/ravpn/output.log";
        open my $fh, "<", "$input" or die "could not open '$input': $!";
        while (<$fh>){
            if ($_ =~ /(................)fw.*(Group = NETOPS_TUNNEL). (Username = .(authenticated.)/){
                push (@results, "$1 $2 $3 $4<br>")
            }
        }
        return @results
    }

    sub expand  { 
        my $file=shift; 
        $file=~s{(\d+)}{sprintf "%04d", $1}eg; # expand all numbers to 4 digits
        return $file;
    }

    sub sendmailnew {
        my %params; 
        my @results = @{$_[0]};
        $params{sorted} = "@results";
        my %options; 
        $options{INCLUDE_PATH} = '/usr/local/CCS/ravpn/templates/'; 
        my $msg = MIME::Lite::TT::HTML->new( 
            From        =>  "",
            #To          =>  "", 
            BCC                 =>  "",
            Subject     =>  "", 
            Encoding    => 'quoted-printable',
            Template    =>  {
                text    =>  'test.txt.tt',
                html    =>  'sort.html.tt',
            },
            TmplOptions =>  \%options, 
            TmplParams  =>  \%params, 
        ); 

        $msg->send;
        system("rm -rf /usr/local/CCS/ravpn/output.log");
    }

Когда он запускается из командной строки, он переходит в каталог / var / log / fw_d, получает все записи, которым менее 30 дней, и передает их вменьше и grep работает с ними, результаты выводятся в output.log.(этот файл создается при запуске через crontab, но ничего не выводится).При запуске из командной строки записи добавляются в файл output.log

. После создания файла output.log, который сканируется на предмет определенного набора элементов, а результаты помещаются в массив, называемый results,который затем отправляется по электронной почте.

Этот сценарий отлично работает, если он запускается вручную, но если он запускается из crontab, либо пользователь, которого мы используем для создания журналов, либо пользователь root, он не может ничего вывести на выход.файл журнала.

У меня такое ощущение, что все будет просто, но я не уверен.

это запись crontab -e

  40 03 * * * perl /usr/local/CCS/ravpn/ravpn.pl    

Файлы, которыечитаются либо обычный текст, либо заархивированные текстовые файлы, .gz, поэтому мне нужен был способ чтения их без разархивирования, следовательно, использование less.

Любая помощь приветствуется.

1 Ответ

2 голосов
/ 25 ноября 2011

Попробуйте заменить

system("/usr/bin/less -f $fulldir/$configs | /bin/grep NETOPS_TUNNEL >> /usr/local/CCS/ravpn/output.log");

с

system("/bin/cat $fulldir/$configs | /bin/grep NETOPS_TUNNEL >> /usr/local/CCS/ravpn/output.log");

Меньше не предназначено для работы без терминала. Там нет необходимости делать это в вашем случае. Еще лучше, если вы выполните эту операцию внутри perl без вызова system с использованием собственных функций perl:

if ($configs =~ /\.gz$/) {
    open (F1, "gunzip -c $fulldir/$configs |");
} else {
    open (F1, "$fulldir/$configs");
}
open (F2, ">> /usr/local/CCS/ravpn/output.log");
while (<F1>) {
    print F2 $_ if (/NETOPS_TUNNEL/);
}
close F2;
close F1;

PS: я вижу, что вы используете /usr/local/CCS/ravpn/output.log в качестве временного файла. Нет необходимости в этом файле в зависимости от того, что делает этот скрипт. Это делает ваш сценарий еще проще.

Редактировать: работает и с файлами .gz. Вы также можете использовать IO :: Uncompress :: Gunzip, но это уже сложнее.

...