/ / Lectura de un archivo que podría estar truncado en Perl - perl, file-io, truncado

Lectura de un archivo que podría estar truncado en Perl - perl, file-io, truncado

Estoy usando Perl para leer un archivo de registro quepodría ser truncado en cualquier punto. Si esto sucede, quiero comenzar a leer el archivo al principio otra vez, pero el comportamiento predeterminado de Perl parece ser esperar hasta que el puntero del archivo se haya puesto al día. Por ejemplo, si ejecuto lo siguiente:

perl -e "open FILE, "test"; while (1) { $line = <FILE>; print "$line"; }"

y luego hacer:

for i in 1 2 3; do echo $i >> test; done
:>test
for i in 4 5 6 7; do echo $i >> test; done

el resultado que obtengo es:

1
2
3
7

Pero si tuviera que hacer lo mismo, reemplazar el código Perl por:

tail -f test

luego (ignorando la salida de cola a stderr) obtengo la salida que deseo, es decir:

1
2
3
4
5
6
7

Obviamente, no puedo usar cola porque quiero hacer algo de procesamiento en la línea en sí misma. Lo único que pensé fue combinar los dos:

tail -f test | perl -e "while (1) { $line = <STDIN>; print "$line"; }"

que funciona en mi máquina de desarrollo de Linux, pero desafortunadamente no en la plataforma de destino de Solaris.

¿Algunas ideas?

Como se solicitó, un ejemplo de uso de File :: Tail es el siguiente:

perl -e "use File::Tail; $file = File::Tail->new("test"); while (defined($line=$file->read)) { print "$line"; }"

Si luego ingreso datos en la prueba como antes, la salida que obtengo es justa:

7

que obviamente no es tan deseado. Intenté ajustar el intervalo máximo que File :: Tail esperará de la siguiente manera:

perl -e "use File::Tail; $file = File::Tail->new(name => "test", maxinterval => 1); while (defined($line=$file->read)) { print "$line"; }"

pero en ese caso, ingrese datos en el archivo de prueba demasiado rápido, de esta manera:

for i in 1 2 3; do echo $i >> test; done; :>test; for i in 4 5 6 7; do echo $i >> test; done

resultados en solo:

4
5
6
7

Desafortunadamente, ese es un escenario realista paranuestra (muy ocupada) aplicación. En aras de la comparación, Linux tail parece manejar ese tipo de velocidad de entrada de datos correctamente, por lo que es bastante claro que se puede hacer (aunque para ser justos, ¿quizás no en Perl ...?)

Respuestas

2 para la respuesta № 1

los Linux tail mando usa el inotify mecanismo para controlar los cambios en el archivo sin tener que sondearlo repetidamente para obtener actualizaciones. Esto le permite responder de manera rápida y confiable a cualquier cambio en el archivo.

Para implementar una funcionalidad similar en Perl, puede usar Linux :: Inotify2 módulo de CPAN. Desafortunadamente, como su nombre indica, este módulo solo funciona en Linux, por lo que no lo ayudará a portar su script a Solaris.

podría poder usar FAM con el SGI :: FAM módulo en su lugar; aún puede caer internamentepara sondear si no hay un mecanismo de notificación de cambio de archivo nativo disponible, pero al menos debería proporcionar una implementación razonablemente buena y probada del sondeo de archivos.


1 para la respuesta № 2

Parece que quieres emular tail en Perl.

  • Si tiene acceso a CPAN, puede usar File::Tail.

    Es Perl puro (no XS) para que pueda ver cómo se implementó en la fuente si no hay acceso CPAN.

  • Ver también PerlFAQ5 ("¿Cómo hago un tail -f en perl?")