There is a reload file, every day a new file is created in which records appear. In the file for the past day, the recording stops. It is required to count and parse it, and write it to the database.

#! /usr/bin/perl use File::Tail; use DBI; use Getopt::Long; use POSIX qw(strftime); $dbh = DBI->connect('DBI:mysql:phone', 'пользователь', 'пароль') or die "Could not connect to database: $DBI::errstr"; $date_string = strftime "%d_%m_%Y", localtime; $filename = "/srv/cdr/cdr_log_26_04_2015.log"; unless (-e $filename){ my $lfh; open($lfh, '>', $filename) or die "Unable to open file $filename : $!"; close($lfh) or die "Unable to close file : $filename $!"; } $file=File::Tail->new(name=>$filename); my $time = time; while ((defined($line=$file->read))||($time<=time+25*60*60)) { my @arr = split(" ", $line); #$arr[0] - Port Address A #$arr[1] - anumber #$arr[2] - bnumber #$arr[3] - Port Address B #$arr[4] - anumber fixed #$arr[5] - bnumber fixed #$arr[6] - date #$arr[7] - time #$arr[9] - duration #$arr[10] - code if (($arr[4] eq "-") && ($arr[5] eq "-")){ $arr[4] = $arr[1]; $arr[5] = $arr[2]; } $query = "INSERT INTO `phone` (`port_address_A`, `anumber`, `port_address_B`, `bnumber`, `duration`, `date`, `time`, `code`) VALUES('$arr[0]', '$arr[4]', '$arr[3]', '$arr[5]', '$arr[9]', STR_TO_DATE('$arr[6]', '%d-%m-%y'), STR_TO_DATE('$arr[7]', '%T'), '$arr[10]');\n"; $dbh->do($query); undef @arr; } $dbh -> disconnect; 

I can not understand why the script weighs more than a day in the processes. After all, according to the condition, it must exit the cycle after 25 hours. In general, ideally, somehow complete it if there are no lines in the file for 6 hours, for example.

  • File :: Tai and this is not it? - Ilya Kozlov
  • no, everything is written there, use inotify, there is another option with select and intermittent checking the file length (if less, then truncated) simple varinat - kill your script in logrotate or send it signal 1 and process. - zb '

2 answers 2

Look at the condition $time <= time + 25*60*60 again. Try to substitute real values ​​here. Here, for example, $ time is April 1st. For example, now is the third of April. What happens in the condition?

  • Thanks, you need $ time <= time - 25 * 60 * 60 - Ilya Kozlov
  • @IlyaKozlov Well, it definitely won't be hanging for days, yes. - Athari
  • pancake hangs vseravno - Ilya Kozlov

The File::Tail documentation is written in English in white:

 read returns one line from the input file. If there are no lines ready, it blocks until there are. 

The call to $file->read blocked and new lines are waiting for which there will never be. Set the alarm:

 my $abort = !1; my $time = time; local $SIG{ALRM} = sub { $abort = 1; }; alarm 10; while ( !$abort && defined($line = $file->read) ) { alarm 0; # чтобы не вылететь, когда уже прочитали last if $abort; # парсим строку, вставляем в БД… ... alarm 10; } 

Thus, the script will not be blocked for more than 10 seconds.

  • For alarm clocks, the code is very convenient to use Time :: Out. - user6550
  • I would cautiously treat this module, it closes $ @. If you keep this in mind, it looks good in general. - Alex Tokarev