2008-10-29 11 views

Respuesta

2

Aunque consumió las líneas para otros fines, he escrito un código que esencialmente hace esto antes.

Todo lo que necesita hacer es registrar el desplazamiento de bytes (con decir) y el nodo-i (con stat) para cada archivo después de que la cola es completa. La próxima vez que se ejecute contra el archivo, primero revise el inodo (con stat) nuevamente. Si el inodo ha cambiado o el archivo es más pequeño que el desplazamiento registrado, entonces se trata de un archivo diferente (eliminado y recreado, log rotado, etc.), por lo que debe mostrarlo desde el principio; de lo contrario, busque en el desplazamiento grabado y muéstrelo desde allí.

2

since hace exactamente que si bien es en C.

+0

Podrías haber editado tu pregunta. – Axeman

2

puede ser este paquete Perl puede ayudar a:

File::Tail::Multi

Derivado de MultiTail, esta biblioteca Perl facilita la cola de una dinámica lista de archivos y líneas de coincidencia/excepción utilizando expresiones regulares completas e incluso mantiene su estado localmente.

EJEMPLO use 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: Crear nuevo objeto ptail
  • Files => archivo de cola/var/adm/messages
  • OutputPrefix => Anteponer el nombre del archivo de inicio de cada línea en el atributo de objeto "LineArray "
  • $tail1->read: Leer toda la línea de los archivos
  • $tail1->print: Imprimir toda la línea de atributo de objeto "LineArray";
+0

¡Esa * respuesta * es la respuesta perl! – Axeman

+0

Aquí se mantiene el estado, pero solo en una ejecución del programa. Me gustaría que el estado se guarde en las ejecuciones de programas. –

2

he implementado una versión mínima de una versión pura 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: Es casi como su algoritmo, excepto que yo no uso dicen, pero mantiene un contador interno.

Cuestiones relacionadas