2011-12-05 15 views
7

Digamos que quiero ejecutar un programa externo desde mi script con backticks y al mismo tiempo quiero capturar STDOUT y STDERR pero en dos variables diferentes . ¿Cómo puedo hacer eso? Para istance si funciono este script ...Cómo capturar STDOUT y STDERR en dos variables diferentes usando Backticks en Perl

my $cmd = `snmpwalk -v $version -c $community $hostname $oid`; 

... si no hay error todo funciona muy bien, pero si la orden de elevar un error será impreso este error en la línea de comandos y no hacer quiero que eso suceda Quiero capturar el error también. Nada tiene que estar impreso en la pantalla. ¿Algunas ideas?

+2

Es posible que desee echar un vistazo a [Net -SNMP] (http://search.cpan.org/~dtown/Net-SNMP-v6.0.1/). Con eso tendrás un control de error completo y no tendrás que preocuparte por redirigir la salida a otro lugar. –

Respuesta

5

En el Perl FAQ tienes diferentes opciones dependiendo de cómo quiere proceder:

http://perldoc.perl.org/perlfaq8.html#How-can-I-capture-STDERR-from-an-external-command%3f

+0

* Backticks y open() solo leen el STDOUT de su comando. * Parece que no puedo capturar STDERR, debo usar Open3, gracias para la respuesta por cierto! – raz3r

+1

mientras este faq es correcto, es innecesario innecesariamente complicado y OMI incompleto. Si bien el lenguaje básico de Perl hace esto difícil, hay módulos que pueden ayudar, vea mi respuesta para ejemplos usando ['Capture :: Tiny'] (http://p3rl.org/Capture::Tiny) –

8

La única manera de hacer esto con acentos abiertos es redirigir a un archivo dentro del comando shell:

my $cmd = `snmpwalk -v $version -c $community $hostname $oid 2>error.dat`; 

Si desea capturar el STDERR dentro del guión, es necesario IPC::Open3 en lugar de acentos abiertos

+0

Bueno, no tengo que manejar los errores (porque son más como advertencias para mí), por lo que esa solución puede ser adecuada para mí. Voy a intentarlo en este momento :) – raz3r

+0

No funciona :(error.dat está vacío y todavía se producen errores en la línea de comando :( – raz3r

+1

No sé por qué no debería funcionar. Si está creando el archivo , entonces el shell está funcionando como se esperaba. Solo puedo suponer que snmpwalk está produciendo el error por algún otro mecanismo que no sea imprimir en STDERR, pero no sé qué. Iba a decir, si no quieres la salida de todos modos, '2>/dev/null', pero si el caso de error.dat no funciona, tampoco lo hará, probablemente. –

11

No necesita ir hasta open3, que IIRC es solo para cuando necesita leer y escribir en un comando externo, e incluso entonces hay otros métodos.

Para su problema, sugiero usar Capture::Tiny, que puede capturar (o incluso enviar) a STDOUT y STDERR de todo lo que se ejecute dentro de su bloque. Por ejemplo, por su pregunta:

#!/usr/bin/env perl 

use strict; 
use warnings; 

use Capture::Tiny qw/capture/; 

... 

my ($stdout, $stderr) = capture { 
    system ("snmpwalk -v $version -c $community $hostname $oid"); 
}; 

Para otro ejemplo consideran este código funcionamiento:

#!/usr/bin/env perl 

use strict; 
use warnings; 

use Capture::Tiny qw/capture/; 

my ($stdout, $stderr) = capture { 
    system ("echo 'hello'"); 
    system ("date"); 
    warn "Arg1!"; 
}; 

print "STDOUT:\n$stdout"; 
print "STDERR:\n$stderr"; 

la que sólo me dio:

STDOUT: 
hello 
Mon Dec 19 23:59:06 CST 2011 
STDERR: 
Arg1! at ./test.pl line 11. 
Cuestiones relacionadas