Página 1 de 1

Expect.pm tratamiento de errores

NotaPublicado: 2017-12-21 10:15 @469
por alperez
Hola.

Estoy usando el módulo para realizar expect y spawn a través de un script en perl (Con Expect.pm) y no veo la forma de poder capturar la salida de errores para cuando me dé algún problema el script.

Re: Expect.pm tratamiento de errores

NotaPublicado: 2017-12-21 10:58 @499
por explorer
Pero, ¿te refieres a errores del propio script o a errores que detecte Expect cuando dialoga con el otro sistema?

Según la documentación, existe el método error(), que devuelve el último error detectado.

También puedes activar el log de actividad, que es lo más normal para saber qué está ocurriendo, por ejemplo a un archivo:

$object->log_file("filename");

o a la salida estándar

$object->log_stdout(1);


También se puede hacer de otra manera. Normalmente se llama al método expect() en contexto escalar, pero si lo haces en contexto de lista te devuelve más información:

my ($matched_pattern_position, $error, $successfully_matching_string, $before_match, and $after_match) = $object->expect($timeout, @match_patterns);


Del manual:

El segundo valor que devuelve, $error, es el error que obligó regresar a expect(). $error contendrá un número seguido de una cadena equivalente que expresa la naturaleza del error. Los posibles valores son: undef, que indica que no hubo error; '1:TIMEOUT' que indica que pasaron $timeout segundos sin que ocurriera una coincidencia de patrones; '2:EOF' que indica que se leyó un fin de archivo desde $object; '3: spawn id($fileno) died' que indica que el proceso salió antes de realizar la coincidencia; y '4:$!' que indica que se estableció cualquier otro tipo de error en $ERRNO durante la última lectura sobre el identificador de archivo de $object o durante un select(). Todos los identificadores de archivo apuntados por el método set_group(), más STDOUT, tendrán datos que mostrar que $object les mandó durante expect(), si se establecieron log_group() o log_stdout().

Re: Expect.pm tratamiento de errores

NotaPublicado: 2018-01-10 07:26 @352
por alperez
Hola.

Muchas gracias por la información ya que el método en concepto de lista no lo había visto. Solo me centré en el concepto escalar y en obtener el método error() pero la salida que genera no era del todo concluyente.

He probado como has comentado pero no sé si será por algo en el código o la forma de obtener los datos pero no está quedando del todo claro la salida de la variable error. Es decir, he probado con el código que tengo a hacer las pruebas de fallo que creo que voy a tener en caso de algún problema y es por ejemplo que no se llegue a la IP que me quiero conectar y que no esté el fichero en local que voy a mandar y que se mande bien el fichero.

Para el caso de la conectividad me sale:

Error: 3:Child PID 18553 exited with status 65280

Para el caso de que se manda todo correctamente:

Error: 3:Child PID 18424 exited with status 0

Y por último, para el caso de que el fichero que voy a mandar no exista da el mismo estado que el que he mandado sin problemas:

Error: 3:Child PID 18658 exited with status 0

A lo que me refería con capturar estos errores sería a que pensaba que aquí daría algún error al no existir en local el fichero pero realiza todo bien.

Pego el código por si hubiera algo mal.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. #use strict;
  4. use Expect;
  5.  
  6. my $password = "admin";
  7. my $command = "sftp admin\@XX.XX.XX.XXX";
  8. my $spawn_ok = 0;
  9. my $timeout = 10;
  10. my $logfile = "FTPLOGFILE.txt";
  11.  
  12. #print "$command \n";
  13.  
  14. system("rm -rf $logfile");
  15.  
  16. my $exp = new Expect();
  17. $exp->log_file($logfile);
  18. $exp->log_stdout(0);
  19. $exp->spawn("$command") or die "Cannot spawn $!\n";
  20.  
  21. #my $before1 = $exp->before();
  22. #print("Before --> *$before1*\n");
  23. #print("\n");
  24. #my $error1 = $exp->error();
  25. #print("Error --> *$error1*\n");
  26.  
  27. ($matched_pattern_position, $error, $successfully_matching_string, $before_match, $after_match) = $exp->expect($timeout,[ 'admin\@XX.XX.XX.XXX\'s password:',
  28.                    sub {
  29.                                 #$spawn_ok = 1;
  30.                                 my $fh = shift;
  31.                                 #print "Sending password\n";
  32.                                 $fh->send("$password\r");
  33.                                 exp_continue;
  34.                           }
  35.                 ],
  36.                 [ 'sftp> ',
  37.                   sub {
  38.                           my $fh = shift;
  39.                           #$spawn_ok = 3;
  40.                           #print "Send Files\n";
  41.                           $fh->send("put /admin/prueba.txt /C:/Users/admin/\r");
  42.                           $fh->send("exit\r");
  43.                           exp_continue;
  44.                           }
  45.                  ]);
  46.  
  47. print("Match Pattern Position: $matched_pattern_position\n");
  48. print("Error: $error\n");
  49. print("Successfully matching string: $successfully_matching_string\n");
  50. print("Before Match: $before_match\n");
  51. print("After Match: $after_match\n");
  52.                  
  53. #print("\n");
  54. #my $before = $exp->before();
  55. #print("Before --> *$before*\n");
  56. #print("\n");
  57. #my $error2 = $exp->error();
  58. #print("Error --> *$error2*\n");
  59.  
  60. $exp->soft_close();
Coloreado en 0.014 segundos, usando GeSHi 1.0.8.4


Saludos.

Re: Expect.pm tratamiento de errores

NotaPublicado: 2018-01-10 08:55 @413
por explorer
Si se trata de un archivo que está en el mismo directorio o sistema de archivos en donde se está ejecutando el programa, se puede comprobar si existe o no con la ayuda de un operador del tipo -X:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. if (not -e $archivo) {
  2.     say "ERROR: no existe archivo [$archivo]";
  3. }
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4

No sé si te refieres a esto.

Tienes más información en perldoc -f -X

Re: Expect.pm tratamiento de errores

NotaPublicado: 2018-01-10 09:34 @440
por alperez
Me refiero a que me gustaría saber realmente, sin tener que tenerlo en cuenta en el destino, si el fichero o ficheros que mando a través del Expect se han mandado correctamente sabiendo que el comando se ha ejecutado correctamente.

Es un poco lioso, pero me gustaría tener ese control sobre el script y no tener que poner elementos de supervisión aparte para saber que la ejecución se hizo bien con el fichero en la carpeta destino.

Re: Expect.pm tratamiento de errores

NotaPublicado: 2018-01-11 14:10 @632
por explorer
Pues... yo no soy muy experto en Expect, así que no sé si eso es posible.

¿Sabes que se ha instalado correctamente el archivo en el destino? Una forma sería calcularle un MD5 y compararlo con el del original, pero es muy posible que no exista el comando md5sum en el equipo remoto, o que incluso podamos ejecutar algo allí.

Veo que estás usando sftp para mover los archivos. Entonces, estás usando Expect para conectarte a una máquina, y con el sftp, llevar un archivo local tuyo a esa máquina. ¿Es correcto? Entonces, ¿por qué no usar directamente Net::SSH2::SFTP o alguno de los otros módulos sftp para llevar archivos locales hacia/desde sistemas remotos? Controlas la presencia de los archivos locales por medio de test. Y la comunicación está asegurada por el propio protocolo, o devolverá un error muy claro.

Como último recurso, se me ocurre bajarme el archivo para ver si es igual al que tenía antes.

Re: Expect.pm tratamiento de errores

NotaPublicado: 2018-01-15 09:42 @446
por alperez
Ok, explorer, voy a probar con el módulo y ver si me vale.

¡¡Muchas gracias!!