2008-10-29 6 views

Odpowiedz

2

Mimo że pochłonęła linie do innych celów, napisałem kod, który w zasadzie to robi wcześniej.

Wszystko, co musisz zrobić, to nagrać bajt przesunięcie (z powiedzieć) i-węzeł (z stat) dla każdego pliku po ogon jest kompletna. Następnym razem, gdy jest uruchamiany względem pliku, najpierw sprawdź ponownie i-węzeł (z stat). Jeśli i-węzeł zmienił się lub plik jest mniejszy niż zarejestrowany offset, to jest to inny plik (usunięty i utworzony, log został obrócony itd.), Więc powinieneś pokazać go od początku; w przeciwnym razie, należy wyszukać do zarejestrowanego przesunięcia i wyświetlić go z tego miejsca.

2

since robi dokładnie to mimo że jest w C.

+0

Mogłeś właśnie zmienić swoje pytanie. – Axeman

2

Może być to pakiet Perl może pomóc:

File::Tail::Multi

Pochodzące z multitail ta biblioteka Perl ułatwia ogona dynamicznego lista plików i mecz/oprócz linii używających pełnych wyrażeń regularnych, a nawet utrzymuje ich stan lokalnie.

PRZYKŁAD użycie File :: Tail :: Multi;

$tail1=File::Tail::Multi->new ( OutputPrefix => "f", 
           Debug => "$True", 
           Files => ["/var/adm/messages"] 
          ); 
while(1) { 
    $tail1->read; 
    # 
    $tail1->print; 
    sleep 10; 
} 
  • $tail1=File::Tail::Multi->new: Tworzenie nowego obiektu ptail
  • Files => plik Tail/var/adm/messages
  • OutputPrefix => Prepend nazwa początku pliku każdej linii atrybutu obiektu „LineArray "
  • : Czytaj całą linię z plików
  • $tail1->print: Wydrukuj wszystkie linie w atrybucie obiektu" LineArray ";
+0

To * ma * być odpowiedzią perla! – Axeman

+0

Tutaj stan jest utrzymywany, ale tylko w jednym wykonaniu programu. Chciałbym, aby stan został zapisany między programami. –

2

I wdrożone minimalną wersję czystej wersji Perl:

#! /usr/bin/perl 
# Perl clone of since(1) 
# http://welz.org.za/projects/since 
# 

use strict; 
use warnings; 

use Fcntl qw/ SEEK_SET O_RDWR O_CREAT /; 
use NDBM_File; 

my $state_file = "$ENV{HOME}/.psince"; 

my %states; 
tie(%states, 'NDBM_File', $state_file, O_CREAT | O_RDWR, 0660) 
     or die("cannot tie state to $state_file : $!"); 

while (my $filename = shift) { 
     if (! -r $filename) { 
       # Ignore 
       next; 
     } 
     my @file_stats = stat($filename); 
     my $device = $file_stats[0]; 
     my $inode = $file_stats[1]; 
     my $size = $file_stats[7]; 
     my $state_key = $device . "/" .$inode; 
     print STDERR "state_key=$state_key\n"; 

     if (! open(FILE, $filename)) { 
       print STDERR "cannot open $filename : $!"; 
       next; 
     } 

     # Reverting to the last cursor position 
     my $offset = $states{$state_key} || 0; 
     if ($offset <= $size) { 
       sysseek(FILE, $offset, SEEK_SET); 
     } else { 
       # file was truncated, restarting from the beginning 
       $offset = 0; 
     } 

     # Reading until the end 
     my $buffer; 
     while ((my $read_count = sysread(FILE, $buffer, 4096)) > 0) { 
       $offset += $read_count; 
       print $buffer; 
     } 
     # Nothing to read 
     close(FILE); 
     $states{$state_key} = $offset; 
} 

# Sync the states 
untie(%states); 

@Dave: To prawie jak swoim algorytmie, oprócz tego, że nie używam powiedzieć, ale wewnętrzny utrzymuje licznik.