2012-08-08 8 views
7

Ho un programma che dovrebbe eseguire una serie di altri programmi e raccogliere il loro output per scopi di registrazione. Tutto funziona bene fino a quando non viene emesso output standard.Registrazione dall'output in Perl

Questo mi porta ai miei due problemi:

  1. Come posso catturare sia STDIN e STDERR di un altro programma in un unico file?

  2. Se non v'è alcun output a tutti (o uscita solo STDERR) il programma otterrà bloccati sulla linea:

    while (<$input>) 
    

Come posso rendere il programma di attesa per una possibile uscita da un altro programma di tempo di esecuzione indeterminato, e continua ancora se non viene emesso alcun output al termine dell'esecuzione del programma.

qui è che la sezione del codice

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 è il mio gestore di file usato per scrivere al mio file di registro e @errors viene utilizzato per la segnalazione internamente errori nel mio programma.

EDIT: Un problema che ho sperimentato con provare il percorso Proc::Reliable è che sembra avere effetti sulla dopo STDOUT e STDERR, e avrei bisogno di risolvere quelli dopo ogni chiamata a correre. Questo porta ad un altro problema nel mio codice. Sono in esecuzione in parallelo e ogni modifica STDOUT e STDERR effetto tutti i thread (che utilizzano Windows, almeno).

IO::CaptureOutput ha lo stesso problema per me, ma si cerca di correggere la jumbling STDOUT e STDERR internamente e provoca il seguente errore si verifichi:

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

possibile duplicato di [Come si acquisiscono stderr, stdout e il codice di uscita tutto in una volta, in Perl?] (Http://stackoverflow.com/questions/109124/how-do-you-capture-stderr- stdout-e-il-uscita-codice-all-at-once-in-perl) – daxim

risposta

1

Se si avvia da una shell POSIX-like, quindi la notazione 2>&1 invia standard error allo stesso posto di lo standard output:

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

Sia l'output standard che l'errore standard vengono inviati all'ingresso standard dello script di registrazione Perl.

Il ciclo di input nello script del registratore rimarrà in attesa fino a quando non ci sarà un input da leggere, o finché tutti i processi con la pipe aperta per la scrittura chiudono la pipe (in genere perché escono).