2008-10-29 12 views

Antwort

2

Obwohl es die Zeilen für andere Zwecke verbraucht, habe ich Code geschrieben, der im Wesentlichen dies vor.

Alles, was Sie tun müssen, ist die Byte-Offset aufzeichnen (mit sagen) und inode (mit stat) für jede Datei, nachdem der Schwanz abgeschlossen ist. Wenn Sie das nächste Mal mit der Datei arbeiten, überprüfen Sie den Inode (mit stat) erneut. Wenn der Inode geändert wurde oder die Datei kleiner ist als der aufgezeichnete Offset, dann ist es eine andere Datei (gelöscht und neu erstellt, Protokoll wurde gedreht usw.), also sollten Sie es von Anfang an anzeigen; Andernfalls suchen Sie zum aufgezeichneten Offset und zeigen Sie von dort an.

2

since ist genau dass, obwohl es in C ist

+0

Sie könnten gerade Ihre Frage bearbeitet haben. – Axeman

2

dieses Paket Perl sein können, können Sie helfen:

File::Tail::Multi

von multitail Abgeleitet diese Perl-Bibliothek macht es einem dynamischen Schwanz leicht Liste der Dateien und Übereinstimmung/ausgenommen Zeilen mit vollen regulären Ausdrücken und behält sogar ihren Zustand lokal.

Beispiel Verwendung Datei :: 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: Neues PTAIL Objekt
  • Files => Schwanz Datei/var/adm/messages
  • OutputPrefix => Anfügen der Name der Datei Anfang jeder Zeile in Objektattribut „Linearray "
  • $tail1->read: Lesen Sie alle Zeilen von Dateien
  • $tail1->print: drucken Sie alle Zeilen in Objektattribut "Linearray";
+0

Das ist * bekam * die Perl-Antwort zu sein! – Axeman

+0

Hier wird der Zustand beibehalten, aber nur in einer Ausführung des Programms. Ich möchte, dass der Status über Programmausführungen hinweg gespeichert wird. –

2

ich eine Minimalversion einer reinen Perl-Version implementiert:

#! /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: Es ist fast wie Ihr Algorithmus, mit der Ausnahme, dass ich nicht sagen verwenden, sondern einen internen Zähler gehalten.