Bienvenido a los foros de Perl en Español, jonhperl.
Efectivamente, ese es el problema: que el programa
tail nunca regresa.
Una forma sencilla de hacerlo sería, primero, haciendo un
$|=1; al principio del CGI para evitar que haya cacheo de la salida. Luego, en lugar de usar el comando
tail del sistema, podrías usar el módulo
File::Tail, que realiza la misma operación, pero te permite ejecutar tu código línea a línea nueva de access.log, que enviarás a la salida estándar.
Así, el CGI nunca termina, y envía una línea del access.log (o más de una si las hubiere) a la página.
Lo malo es que no se trataría de una página HTML normal, ya que nunca se terminaría de forma automática, sino que pararía por orden del usuario o por un
timeout del servidor. Y además, no es compatible con todos los navegadores, que a veces esperan a que la conexión termine para representar toda la página.
Otra forma de hacerlo: cuando el usuario desea ver el access.log, lo pasas a una página HTML que tiene puesta la opción de autorefrescarse cada X segundos. El refresco consiste en llamar a un CGI, que genera una página con las últimas N líneas de access.log (también con la ayuda de tail -N, por ejemplo). La ventaja es que con esta solución no hay programas funcionando y terminas la conexión HTTP enseguida. La desventaja es que si hay mucho movimiento en access.log, el usuario puede perder la vista de algunas líneas. Esto último se puede resolver usando
cookies o una
query con fecha, en la URL.
Esto mismo se puede realizar en forma de Ajax, pero la única diferencia es en la parte de presentación, no la de servidor. Con
CGI::Ajax también lo puedes hacer.