• Publicidad

Cómo enviar instrucciones a un programa desde Perl

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Re: Cómo enviar instrucciones a un programa desde Perl

Notapor Alfumao » 2011-09-14 04:21 @222

¿Cómo lo ves así?

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!c:/perl/bin/perl.exe
  2. use warnings;
  3. use strict;
  4. use diagnostics;
  5. use CGI ':standard';
  6.  
  7. ####################HTML OMITIDO
  8.  
  9. my $target = param('file');
  10. my $mTPP   = param('mitoProb');
  11.  
  12. ##################SUBIDA DE REPORT REMOTO####################################
  13. my $filename = "$^T" . "$target";
  14. my $lightweight_fh;
  15. my $io_handle;
  16. my $bytesread;
  17.  
  18. $lightweight_fh = upload('file');
  19.  
  20. if ( defined $lightweight_fh ) {
  21.  
  22.     $io_handle = $lightweight_fh->handle;
  23.     open( OUTFILE, '>' . "C:/xampp/htdocs/DB/Uploads/$filename.txt" );
  24.     binmode(OUTFILE);
  25.  
  26.     while ( $bytesread = $io_handle->read( my $buffer, 1024 ) ) {
  27.         print OUTFILE $buffer;
  28.     }
  29. }
  30.  
  31. ##################FIN SUBIDA DE REPORT REMOTO####################################
  32.  
  33. my $upload = "Uploads/$filename" . "\.txt";
  34.  
  35. &TParser($upload);
  36.  
  37. sub TParser {
  38.  
  39.     my $upload = @_;
  40.     open( INFILE, "$upload" ) or die("ERROR: $!\n");
  41.     chomp( my @lineas = <INFILE> );
  42.  
  43.     open SALIDA, '>' . "C:/xampp/htdocs/DB/Results/TP_parsed_$filename.txt" or die "ERROR: $!\n";
  44.  
  45.     for (@lineas) {
  46.         if (/^\w+\s+\d+/) {
  47.             my ( $seqid, $seqlen, $mTP, $SP, $other, $loc, $RC, $TPlen ) = split( /\s+/, $_ );
  48.             if ( $loc eq "M" ) {
  49.                 if ( $mTP >= "$mTPP" ) {
  50.                     print SALIDA ( "$seqid\t" . "$mTP\t" . "$loc\t\n" );
  51.                 }
  52.             }
  53.         }
  54.     }
  55.     close INFILE;
  56.     close SALIDA;
  57. }
  58. #################FIN TP_PARSER##############
  59. my $p_report = "TP_parsed_$filename.txt";
  60.  
  61. print
  62.     qq(<A HREF='Results/$p_report' TARGET='_blank'>-Open in browser or Right click to download file-</A><br><br><br><br><br>\n);
  63. ####################HTML OMITIDO
  64.  
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4
Última edición por Alfumao el 2011-09-27 16:32 @730, editado 3 veces en total
Alfumao
Perlero nuevo
Perlero nuevo
 
Mensajes: 178
Registrado: 2009-12-10 11:20 @514

Publicidad

Re: Cómo enviar instrucciones a un programa desde Perl

Notapor explorer » 2011-09-14 09:14 @426

* 7. Si en ese código HTML omitido está la llamada a header(), perfecto.

* 23. Mi versión es esta:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     open OUTFILE, '>', "C:/xampp/htdocs/FUNGALOXPHOS_CSS/Uploads/$filename.txt" or die "ERROR: $!\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


* 33.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $upload = "Uploads/$filename.txt";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


* 39. Error. Lo correcto es
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     my($upload) = @_;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


* 43.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     open SALIDA, '>', "C:/xampp/htdocs/FUNGALOXPHOS_CSS/Results/TP_parsed_$filename.txt" or die "ERROR: $!\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


* 47.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.             my ($seqid, $seqlen, $mTP, $SP, $other, $loc, $RC, $TPlen) = split;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


* 48 a 52.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.             if ( $loc eq "M" and $mTP >= "$mTPP" ) {
  2.                 print SALIDA "$seqid\t$mTP\t$loc\t\n";
  3.             }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Cómo enviar instrucciones a un programa desde Perl

Notapor Alfumao » 2011-09-15 05:14 @260

Hola explorer,

Gracias una vez más por tu respuesta.

El header lo pongo justo después de los módulos de Perl en el código HTML.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. print "content-type: text/html\n\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


La cosa es que sigue sin funcionar bien el CGI aún habiendo hecho los cambios que apuntabas. Ya no sé qué podrá ser, estoy completamente descorazonado con el tema este. Seguiré probando cosas y si encuentro alguna solución os la postearé. Pero por el momento me encuentro completamente sin fuerzas... han sido demasiados días seguidos sin encontrar soluciones (y lo que es peor, sin que expertos como tú y los demás de este foro tampoco veáis fallos importantes qué reseñar y que pudieran solucionar el problema...).

Un saludo y ya os contaré si logro algo.
Alfumao
Perlero nuevo
Perlero nuevo
 
Mensajes: 178
Registrado: 2009-12-10 11:20 @514

Re: Cómo enviar instrucciones a un programa desde Perl

Notapor explorer » 2011-09-15 05:45 @281

No necesitas escribir todo ese mamotreto de línea para mandar las cabeceras.

Si te hubieras fijado en los CGI que hay por estos hilos (y en el CGI mínimo en particular), verías que toda esa línea se puede reducir a
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
print header;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

gracias a la presencia del módulo CGI.


En cuanto al desarrollo...

Yo te aconsejo que adoptes la técnica del "paso a paso" junto con la de "dónde demonios estamos".

La primera técnica se refiere a que construyas un cgi que, simplemente, funcione, aunque no haga nada. Y a continuación, irle agregando más pasos. Por cada paso, lo vuelves a ejecutar. Y no solo miras el resultado en la ventana del navegador: también debes mirar el código HTML que se ha generado, y también debes mirar los registros que el servidor web ha guardado en los ficheros log.

En cuanto llegues a un paso que provoque un error, sabrás que has localizado la primera piedra del camino. Repasa las líneas que acabas de meter, y si no ves qué es lo que pasa, lo mandas aquí.

La segunda técnica consiste en poner print() en todos los pasos del programa, del estilo: print "El programa acaba de leer la lista de todos los parámetros CGI\n";, o print "Parámetros pasados al programa: ", param(), "\n";, o print "Ejecutando programa externo [$comando]\n";.

En tu caso, el principal problema quizás sea la ejecución de programas externos. Bueno, pues la misma línea que le pasas a system() o qx(), antes se la pasas a print(), para ver qué es lo que estás ejecutando.

También, debes comprobar si lo que esperas, existe: si esperas leer un fichero, debe haber un die() si ese fichero no existe. Si ejecutas un programa y como resultado de ello debe generarse un fichero, con un test -e puedes comprobar que realmente se ha creado. Etc.

Aquí hay una "pequeña" dificultad añadida: al ser un cgi, los print() normales saldrán dentro del código HTML generado, por lo que seguramente saldrá mezclado y no se verá bien. Hay dos opciones:
  • en vez de print(), a veces suelo usar warn(), que lo que hace es enviar esos mensajes al fichero error.log del servidor web. O, también:
  • la salida de un print la embuto dentro de una marca HTML <pre>, así: print pre("mensaje: ");. Así, la salida sale preformateada en letra monoespaciada, y es más fácil de ver (como por ejemplo, las salidas del Dumper() de Data::Dumper).

También dices que si ejecutas los programas desde la línea de comandos, funcionan. Entonces, yo deduzco que el problema no está con los programas Perl, sino con su ejecución por parte del servidor web. Con las técnicas anteriores sabrás dónde falla.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Cómo enviar instrucciones a un programa desde Perl

Notapor Alfumao » 2011-09-15 07:28 @353

Ok, explorer, iré probando todo lo que me dices, pero antes te comentaré una cosa.

Los CGI me funcionan si el archivo sobre el que trabajan está en el servidor, es decir, lo pongo en la carpeta principal de la base de datos y el programa hace lo que tiene que hacer sin problemas, con lo que el resultado se obtiene perfectamente en la página web.

Ahora bien, si he de subirlo desde "fuera del servidor", como por ejemplo desde el escritorio de mi ordenador, el programa no funciona.

Siempre he creído y así lo he expresado anteriormente, que hay algún problema con la subida del fichero mediante la parte de "UPLOAD CGI", porque es ahí (cuando incluyo dicha parte) donde todo deja de funcionar, aunque sería raro que fuera un problema de la emulación del servidor por parte del XAMPP, ya que en el caso del HMMer que tratamos en las páginas anteriores de este mismo post, apliqué las soluciones que me propusiste y funcionó bien... de ahí mi falta de ideas e incapacidad para resolver el asunto.
Alfumao
Perlero nuevo
Perlero nuevo
 
Mensajes: 178
Registrado: 2009-12-10 11:20 @514

Re: Cómo enviar instrucciones a un programa desde Perl

Notapor explorer » 2011-09-15 13:34 @607

Bien... entonces, aplicando la técnica del "paso a paso", modificas el programa para que haga el upload, pero que al final de ese proceso, saque el lugar y tamaño del fichero que acaba de leer. Con un print(), sacas la ruta completa del fichero que grabaste con OUTFILE, y con -s a esa misma ruta, sacas el tamaño en bytes del fichero que acabas de subir.

Como tu mismo has hecho la prueba de subir un fichero desde el formulario web, ya sabes qué fichero has subido y por lo tanto, qué tamaño debe tener en la copia.

Ten, en el ordenador, una ventana abierta con la carpeta donde quieres que se guarde el fichero. Ejecuta el formulario, indicando el fichero a subir. Después de pulsar el botón de envío, debes ser capaz de ver aparecer el fichero en esa carpeta. Ahora ya puedes sacarle sus propiedades para ver qué tamaño tiene, y compararlo con el original. Deben ser iguales.

Entonces, si a) está en el directorio correcto, b) tiene el mismo tamaño, y (opcional), c) el contenido es el mismo, sabrás que la parte del upload funciona.

Si no, ¿dónde falla? ¿no lo guarda en el directorio que quieres? ¿lo guarda con una longitud distinta?
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Cómo enviar instrucciones a un programa desde Perl

Notapor Alfumao » 2011-09-16 07:57 @373

Hola explorer,

Por fin he corregido el error. No estaba en el programa de Perl (que funcionaba bien) sino en el HTML, donde tenía mal el método de recogida de info del formulario.

En vez de:
Sintáxis: [ Descargar ] [ Ocultar ]
Using html4strict Syntax Highlighting
  1. METHOD="POST" ENCTYPE="multipart/form-data"
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

tenía:
Sintáxis: [ Descargar ] [ Ocultar ]
Using html4strict Syntax Highlighting
  1. METHOD="GET" ENCTYPE="multipart/form-data"
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Pero la clave para resolverlo me la has dado tú al explicarme lo del archivo "error.log" del servidor.

Allí vi el siguiente error:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
[Fri Sep 16 14:26:02 2011] [error] [client 127.0.0.1] Uncaught exception from user code:, referer: http://localhost/DB/TP_parser.html
[Fri Sep 16 14:26:02 2011] [error] [client 127.0.0.1] \tERROR: No such file or directory, referer: http://localhost/DB/TP_parser.html
[Fri Sep 16 14:26:02 2011] [error] [client 127.0.0.1]  at C:/xampp/htdocs/DB/TP_parser2.cgi line 64, referer: http://localhost/DB/TP_parser.html
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Y gracias a eso revisé de nuevo el HTML donde descubrí ese error de puñetero torpe... se me pasó por alto varias veces, la verdad.

Siento muchísimo el mal rato que he reflejado en mis preguntas aquí, pero es que soy incapaz de rendirme con estas cosas, aunque sea tan negado como lo soy con la programación.

Mil gracias y un saludo.

PD. Para quien le pueda servir, la llamada a la ejecución del BLAST me ha funcionado así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $resultado = qx("C:/Archivos de programa/NCBI/BLAST/bin/$program" -query Uploads/$target -db DBase -evalue 1e-0005 -out Results/$filename.out -outfmt 10);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Alfumao
Perlero nuevo
Perlero nuevo
 
Mensajes: 178
Registrado: 2009-12-10 11:20 @514

Re: Cómo enviar instrucciones a un programa desde Perl

Notapor Alfumao » 2011-10-27 09:11 @424

Hola de nuevo,

Respecto a este tema tengo ahora una pregunta nueva.

Si quiero usar una "tubería" o pipe con el resultado del comando anterior para pasárselo a otro programa, ¿habría que hacerlo así?

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  my $resultado = `"C:/HMMer3/hmmscan.exe" "C:/xampp/htdocs/DB/HMMs/PRESS" "C:/xampp/htdocs/DB/Uploads/$filename.txt" > C:/xampp/htdocs/DB/Results/$filename.out | Phmm.cgi`;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Porque parece que se atasca pero no me da resultado...

Un saludo.
Alfumao
Perlero nuevo
Perlero nuevo
 
Mensajes: 178
Registrado: 2009-12-10 11:20 @514

Re: Cómo enviar instrucciones a un programa desde Perl

Notapor explorer » 2011-10-27 09:42 @445

El problema es el siguiente: con la redirección '>' estás indicando que toda la salida del programa hmmscan.exe debe ser enviado al fichero $filename.out. Y eso también implica que ninguna salida es enviada al programa Phmm.cgi, que se quedará esperando por algo que no llega.

En lugar de poner una tubería recta, lo que debes hacer es colocar una tubería en 'T'.

No sé cómo se hará en MS-DOS, pero en UNIX/Linux existe el comando tee (Te) para hacer eso.

Entonces, la línea sería así (no probado):
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $resultado = qx(C:/HMMer3/hmmscan.exe C:/xampp/htdocs/DB/HMMs/PRESS C:/xampp/htdocs/DB/Uploads/$filename.txt | tee C:/xampp/htdocs/DB/Results/$filename.out | Phmm.cgi);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

  • Hemos cambiado las comillas invertidas por la función qx(), que hace lo mismo
  • Quitamos las comillas dobles. Solo son necesarias si hubiera nombres de ficheros con caracteres espacio
  • Colocamos un tubería 'T' para que la salida quede grabada en el fichero, y al mismo tiempo sea llevada al Phmm.cgi

Otra opción es hacerlo en dos pasos: primero ejecutas hmmscan.exe, y luego Phmm.cgi.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Cómo enviar instrucciones a un programa desde Perl

Notapor Alfumao » 2011-10-29 06:07 @297

Hola explorer,

Lo he solucionado concatenando los programas y así me he ahorrado líos, pero muchas gracias una vez más por tu rápida respuesta.

:wink:
Alfumao
Perlero nuevo
Perlero nuevo
 
Mensajes: 178
Registrado: 2009-12-10 11:20 @514

Anterior

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 22 invitados

cron