2012-08-08 9 views
7

Tengo un programa que se supone que ejecuta un conjunto de otros programas y recopila su salida para fines de registro. Todo funciona bien siempre que haya salida para salida estándar.Logging from output in Perl

Eso me lleva a mis dos problemas:

  1. Como puedo capturar tanto STDIN y STDERR de otro programa en un archivo?

  2. Si no hay salida en absoluto (o salida a STDERR solamente) el programa se queda bloqueado en la línea:

    while (<$input>) 
    

¿Cómo puedo hacer que la espera del programa para una posible salida de otro programa de tiempo de ejecución indeterminado, y aún continúa si no hay salida en el momento en que el programa termina la ejecución.

aquí es que la sección del código

my $pid = open (my $input, '-|', "$prog $args") 
     or push @errors, "A failute has occurred in $prog $args"; 
if(not @errors){ 
    while (<$input>){ #POSSIBLE LOCATION FOR HANG UP IF NO PRINTING IS DONE 
     if($input =~ /^END\n$/){ 
      last; 
     } 
     print $fh $_; 
    } 
} 
else{ 
    print $fh "An error has occurred with executing \"$prog $args\""; 
} 

nota: $fh es mi manejador de archivo que se utiliza para escribir en el archivo de log, y @errors se utiliza para la preparación de información interna errores en mi programa.

EDIT: Un problema que tuvimos con intentar la ruta Proc::Reliable es que parece tener efectos posteriores sobre STDOUT y STDERR, y lo que necesitaría ser reparado los que después de cada llamada a ejecutar. Esto lleva a otro problema en mi código. Estoy corriendo en paralelo y cualquier cambio a STDOUT y STDERR afecta a todos los hilos (usando Windows al menos).

IO::CaptureOutput tiene el mismo problema para mí, sino que trata de corregir la STDOUT y STDERR revoltijo interno y hace que el siguiente error que se produzca:

Couldn't remove temp file 'C:\Users\SBLAKE~1\AppData\Local\Temp\m8E3pUGfOS' - Permission denied at C:/Perl/site/lib/IO/CaptureOutput.pm line 82 
+0

posible duplicado de [¿Cómo capturar stderr, stdout y el código de salida de una sola vez, en Perl?] (Http://stackoverflow.com/questions/109124/how-do-you-capture-stderr- stdout-and-the-exit-code-all-at-once-in-perl) – daxim

Respuesta

1

Si lanza desde un shell POSIX-como, a continuación, la notación 2>&1 envía el error estándar para el mismo lugar que la salida estándar:

some-program-to-be-logged 2>&1 | perl logger.pl -o /chosen/log.file 

Tanto la salida estándar como el error estándar se envían a la entrada estándar del script de registro de Perl.

El bucle de entrada en el script del registrador se colgará en espera hasta que haya entrada para leer, o hasta que todos los procesos con el conducto abierto para escribir cierren el conducto (normalmente porque salen).