• 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-10 09:18 @429

Ahora lo estoy intentando con el programa que me pusiste de ejemplo, el BLAST, pero no parece que funciona la cosa... te pongo el código a ver si puedes detectar en qué he metido la pata esta vez...

Creo que he aplicado todos tus consejos con diligencia. :?

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!c:/perl/bin/perl.exe
  2. use warnings;
  3. use strict;
  4. use CGI ':standard';
  5.  
  6. my $file    = param('file');
  7. my $evalue  = param('evalue');
  8. my $program = param('program');
  9.  
  10. my $filename = "$$" . "$^T" . "$file" . "\.txt";
  11.  
  12. my $lightweight_fh;
  13. my $io_handle;
  14. my $bytesread;
  15.  
  16. $lightweight_fh = upload('file');
  17.  
  18. if ( defined $lightweight_fh ) {
  19.     $io_handle = $lightweight_fh->handle;
  20.     open( OUTFILE, '>>' . "C:/xampp/htdocs/DB/Uploads/$filename" ) || die "failed to open output for write: $!";
  21.     binmode(OUTFILE);
  22.     while ( $bytesread = $io_handle->read( my $buffer, 2048 ) ) {
  23.         print OUTFILE $buffer;
  24.     }
  25.     my $resultado
  26.         = qx("C:/Archivos de programa/NCBI/BLAST/bin/'$program'.exe" -query "C:/xampp/htdocs/DB/Uploads/$filename" -db "C:/Archivos de programa/NCBI/BLAST/db/OXPHOS" -out "C:/xampp/htdocs/DB/Results/$filename.out");
  27.     close OUTFILE;
  28. }
  29. my $report = "C:/xampp/htdocs/DB/Results/$filename.out";
  30. print
  31.     qq(<A HREF='Results/$report' TARGET='_blank'>-Open in browser or Right click to download file-</A><br><br><br><br><br>\n);
  32.  
  33.  
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4
Última edición por explorer el 2011-09-10 09:22 @432, editado 1 vez en total
Razón: Formateado de código con Perltidy
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-10 09:24 @433

De la línea 26, quita todas las comillas, todas. Tanto las dobles como las simples.
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-10 14:24 @642

Pues sigue sin darme ningún resultado quitándole las comillas... la cosa es que no se crea ni el archivo del buffer ni ningún temporal, es como si directamente no cargara el archivo del HTML.

Seguiré probando a ver si hay algún otro error más.

He visto esta posible solución por la web, pero no me funcionó tampoco... esto comienza a ser algo desquiciante.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $blast_location = "C:/Archivos de programa/NCBI/BLAST/bin/$program.exe";
  2. my$input = "C:/xampp/htdocs/DB/Uploads/$filename.txt";
  3. my$output= "C:/xampp/htdocs/DB/Results/$filename.out";
  4. my $database= "DBase";
  5. my $command = `$blast_location -query $input -db $database -evalue 1e.10-5 -out $output -outfmt 6 `;
  6.  
  7. system($command);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Siento ser tan pesado con estas dudas de puñetero torpe...

Por cierto el error que me sale es este:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
¡Acceso prohibido!

Usted no tiene permiso de accesar al objeto solicitado. Existe la posibilidad de que este protegido contra lectura o que no haya podido ser leído por el servidor.

Por favor contacte con el webmaster en caso de que usted crea que existe un error en el servidor.
Error 403
localhost
10/09/2011 21:22:41
Apache/2.2.17 (Win32) mod_ssl/2.2.17 OpenSSL/0.9.8o PHP/5.3.4 mod_perl/2.0.4 Perl/v5.10.1
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Pero tampoco hay ningún fichero de resultados (así que dificilmente lo va a leer).
Última edición por Alfumao el 2011-09-27 16:35 @732, editado 1 vez en total
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-11 07:44 @364

Hummm...

¿Ha de ser, necesariamente, un Perl cgi lo que tienes que hacer?

En ese caso, te has olvidado de poner la llamada al método header() y un start_html() al principio de la salida de texto, y un end_html() al final. Mira mi CGI mínimo.

De otra forma, si no necesitas que sea un cgi, te vale con ejecutarlo desde la línea de comandos. ¿Qué error sale si ejecutas el programa desde una ventana MSDOS?

Si el error sale cuando lo ejecutas como cgi, mira los ficheros de log de actividad del servidor web para ver si te da más información sobre el error.

Estríctamente hablando, el error dice que el cgi no ha podido ser ejecutado porque el (usuario que ejecuta el) servidor web no tiene permisos para acceder a él.

Primero asegúrate de que funciona mi CGI mínimo, y de esa manera sabrás dónde y con qué permisos debes poner el tuyo. Observa que uso el CGI::Carp, para que salgan los errores en la ventana del navegador.
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-11 09:36 @441

Verás, explorer: son 3 programas cuya ejecución me da problemas.

Todos funcionan bien desde la línea de comandos, e incluso, si en vez de hacer el paso de subir el archivo desde una localización remota, lo pongo en la carpeta de la Base de Datos directamente, también me funcionan.

Creo que el problema está en el paso de reescritura del archivo vía IO HANDLE (al menos en dos de ellos, no en el BLAST cuyo problema no alcanzo a entender ya que todo el CGI va a la perfección, es decir, representa en pantalla el código HTML/CSS, y da un enlace al resultado, que eso sí, no aparece por ningún lado, cosa que sigo pensando que se debe al IO HANDLE).

Mi opinión es que como los archivos FASTA (en el caso de BLAST) y los reportes de resultados que usan los otros dos programas para hacer su función de parsing, pierden su formato original al pasarse por el buffer y re-escribirse en la salida del IO HANDLE (las líneas no se conservan separadas, sino que se escriben sin salto de línea "\n" en el fichero de copia resultante) y por eso los parsers no funcionan, ya que están escritos para procesar un fichero con un formato determinado y línea a línea, para así extraer parámetros determinados de cada una, si se cumplen ciertas condiciones, y si esto no va así, no funcionan.

Te pondré el código ejemplo de un parser para ilustrar mejor lo que digo.

Yo opino desde mi poca experiencia, que si no puedo re-escribir (desde el buffer) las líneas una a una y conservar la estructura original del reporte de resultados, no podré hacer funcionar el parser (del BLAST ya ni hablamos...)

Ejemplo de parser:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. chomp(my $target = shift @ARGV);
  7. open(INFILE,"$target") or die ("ERROR: $!\n");
  8. chomp (my @lineas = <INFILE>);
  9. open  SALIDA,'>TP_parsed.txt' or die "ERROR: $!\n";
  10. chomp(my $TProb = shift @ARGV);
  11.  
  12. for(@lineas){
  13.     if (/^\w+\s+\d+/){
  14.         my ($seqid, $seqlen, $mTP, $SP, $other, $loc, $RC, $TPlen) = split(/\s+/, $_);
  15.         if ($loc eq "M"){
  16.             if($mTP >= $TProb){
  17.                 print SALIDA ("$seqid\t"."$mTP\t"."$loc\t\n");
  18.             }
  19.         }
  20.     }
  21. }
  22. close INFILE;
  23. close SALIDA;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Este parser lo ejecuto como hicimos con el HMMer anteriormente en este post:

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 IO::Handle;
  6. use CGI ':standard';
  7.  
  8. ##############HTML OMITIDO
  9.  
  10. my $target= param('file');
  11. my $mTPP= param('mitoProb');
  12.  
  13. my $filename= "$$"."$^T"."$target";
  14.  
  15. my $lightweight_fh;
  16. my $io_handle;
  17. my $bytesread;
  18.  
  19. $lightweight_fh  = upload('file');
  20.  
  21.           if (defined $lightweight_fh) {
  22.               $io_handle = $lightweight_fh->handle;
  23.               open (OUTFILE,'>>'."C:/xampp/htdocs/DB/Uploads/$filename");
  24.               binmode(OUTFILE);
  25.               while ($bytesread = $io_handle->read(my $buffer,2048)) {
  26.                   print OUTFILE $buffer."\n";
  27.               }
  28.               #close OUTFILE;
  29.           }
  30.  
  31. my$archivo = "C:/xampp/htdocs/DB/Uploads/$filename";
  32.  
  33. my $resultado = `A_TParser.pl "$archivo" "$mTPP" > C:/xampp/htdocs/DB/Results/$filename.out`;
  34.  
  35. my $report= "$filename.out";
  36.  
  37. print qq(<A HREF='Results/$report' TARGET='_blank'>-Open in browser or Right click to download file-</A><br><br><br><br><br>\n);
  38.  
  39. ##############HTML OMITIDO
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Y me devuelve un resultado, pero vacío, ya que no puede parsear el reporte por lo que comenté antes de la perdida de formato.

Desde la línea de comandos con el mismo parser, el mismo reporte y el mismo valor de probabilidad ($mTTP) me hace el parsing perfectamente.

PREGUNTA: ¿Puedo conseguir que el IO HANDLE me mantenga el formato del reporte al subirlo al servidor para procesarlo?

Esto no funciona, te lo comento por si era lo obvio...
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  print OUTFILE $buffer."\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Un saludo y disculpa por la gran chapa.
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-11 13:02 @585

Precisamente el error está ahí, en la línea 26
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.               while ($bytesread = $io_handle->read(my $buffer,2048)) {
  2.                   print OUTFILE $buffer."\n";
  3.               }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

En este bucle, lo que queremos hacer es copiar, literalmente, el fichero subido por el usuario, al lugar donde lo vamos a procesar. Para ello, lo vamos leyendo en bloques de hasta 2048 bytes. Y queremos trasladar esos 2048 bytes al nuevo fichero... y ahí está el error: estás añadiendo un "\n" al final de cada bloque de 2048 bytes.

Si te fijas en mi código publicado más arriba, yo no pongo ningún "\n". La copia es literal. La única preocupación que hay que tener es que, si estás en un sistema operativo que distingue entre ficheros en modo binario con los que están en modo texto (como es tu caso de seguir usando Windows), hay que acordarse de colocar el binmode() en el handle de salida. Eso ya lo tienes hecho, pero el problema es que le has añadido el "\n", por lo que estás "rompiendo" el fichero original.

Quítalo, y nos comentas.
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-11 18:20 @805

Ok, explorer, ya entiendo, pero aun así quitando el salto de línea del buffer, siguen saliendome ficheros de resultados vacíos... pero si el programa lo ejecuto desde la línea de comandos así:

-> A_TParser.pl reporte.txt 0.250

Entonces funciona y me devuelve un archivo de salida con el parsing hecho correctamente.

Desesperante, ¡ja,ja,ja,ja! Me rio por no llorar.
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-11 20:18 @888

Me he dado cuenta de otro problema, también por seguir usando Windows.

En la línea 26 de un código anterior, tenías puesto
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $resultado
  2.         = qx("C:/Archivos de programa/NCBI/BLAST/bin/'$program'.exe" -query "C:/xampp/htdocs/DB/Uploads/$filename" -db "C:/Archivos de programa/NCBI/BLAST/db/OXPHOS" -out "C:/xampp/htdocs/DB/Results/$filename.out");
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

y te dije que quitaras todas las comillas.

Bueno, pues no era del todo correcto.

El problema está en que hay directorios que contienen espacios en blanco, como "Archivos de programa".

Creo recordar, que la forma de referirse a ellos, dentro de un programa, era por medio de las comillas dobles, pero no estoy seguro (hace años que dejé de usar Windows).

En ese caso, la línea se escribiría así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $resultado
  2.         = qx("C:/Archivos de programa/NCBI/BLAST/bin/$program.exe" -query C:/xampp/htdocs/DB/Uploads/$filename -db "C:/Archivos de programa/NCBI/BLAST/db/OXPHOS" -out C:/xampp/htdocs/DB/Results/$filename.out);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

La interpolación de las variables la realiza qx(), por lo que desaparecen las comillas dobles para las opciones -query y -out, pero son necesarias para escapar el efecto de los espacios en blanco de $program y -db.

Si los programas funcionan ahora desde la línea de comandos, entonces el problema está en otro sitio, en la configuración del servidor web o en la forma de dialogar con él.

Te recomiendo que empieces por un programa mínimo que sea capaz de ejecutarse de forma correcta, por el servidor web, y luego le vas añadiendo componentes, hasta que llegues a un paso en que falle. Y así sabremos en qué línea y en qué proceso 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-12 04:28 @228

Hola de nuevo, explorer,

He probado tu CGI mínimo.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!c:/perl/bin/perl.exe
  2. # CGI MÍNIMO
  3. # Joaquín Ferrero. 2006.
  4. # Este cgi sirve para comprobar si el servidor funciona con Perl+CGI
  5. #
  6.  
  7. use warnings;
  8. use strict;
  9. use diagnostics;
  10. use IO::Handle;
  11. use CGI ':standard';
  12. use CGI       qw(:standard      );
  13. use CGI::Carp qw(fatalsToBrowser);
  14.  
  15. ####################MAIN#####################
  16.  
  17. my $target= param('file');
  18. my $mTPP= param('mitoProb');
  19.  
  20. my $filename= "$$"."$^T"."$target";
  21.  
  22. my $lightweight_fh;
  23. my $io_handle;
  24. my $bytesread;
  25.  
  26. $lightweight_fh  = upload('file');
  27.  
  28.          if (defined $lightweight_fh) {
  29.            $io_handle = $lightweight_fh->handle;
  30.             open (OUTFILE,'>>'."C:/xampp/htdocs/DB/Uploads/$filename.txt");
  31.             binmode(OUTFILE);
  32.            while ($bytesread = $io_handle->read(my $buffer,2048)) {
  33.              print OUTFILE $buffer;
  34.            }
  35.            my $resultado = `A_TParser.pl "C:/xampp/htdocs/DB/Uploads/$filename.txt" "$mTPP" > C:/xampp/htdocs/DB/Results/$filename.out`;
  36.            close OUTFILE;
  37.          }
  38.  
  39.         my $report= "C:/xampp/htdocs/DB/Results/$filename.out";
  40.  
  41. print qq(<A HREF='$report' TARGET='_blank'>-Open in browser or Right click to download file-</A><br><br><br><br><br>\n);
  42.  
  43. ####################MAIN#####################
  44.  
  45. print
  46.     header,
  47.     start_html('CGI MINIMO'),
  48.     h1('CGI MINIMO'),
  49.     hr,
  50.     p('Si ves este texto es que S&Iacute; est&aacute; funcionando bien.'),
  51.     hr;
  52. # Aquí sacamos la lista de los parámetros
  53. # en caso de que le haya sido pasado alguno
  54. my @parametros = param();
  55. foreach my $par ( @parametros ) {
  56.         print p($par);
  57.         print blockquote(param( $par ));
  58. }
  59.  
  60. print end_html;
  61.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Me dá este resultado:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
CGI MINIMO

Si ves este texto es que SÍ está funcionando bien.

file

    TP_res.txt

mitoProb

    0.300

submit

    Parse file
 
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


¿Parece que los parámetros los coge bien, no?

Yo sigo pensando que hay algo que no funciona en el proceso del io_handle... pero es que es el mismo (los mismos comandos) que sí funcionaban en el caso del HMMer que tratamos anteriormente en el post.
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-13 04:34 @232

No puedes colocar ningún print() antes del print del header(). Tienes la línea 41 antes de la 46. El header() marca al navegador web qué tipo de fichero sigue a continuación, por lo que es necesario que sea lo primero que salga hacia el navegador del usuario.

La línea 11 es igual que la 12.

Otro detalle... el enlace que presentas en la línea 41 es "C:/xampp/htdocs/DB/Results/$filename.out". Con el fichero que has puesto de ejemplo, sería así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using html4strict Syntax Highlighting
  1. <A HREF='C:/xampp/htdocs/DB/Results/TP_res.txt.out' TARGET='_blank'>-Open in browser or Right click to download file-</A><br><br><br><br><br>
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Bueno, pues esa no es la forma correcta de designar los enlaces a los recursos. La notación C:/ no es correcta. Debería ser 'DB/Results/TP_res.txt.out' o algo parecido, relativo a la carpeta que utiliza el servidor web para servir los ficheros.

A lo sumo, habría que cambiarlo por el esquema file://.
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

AnteriorSiguiente

Volver a Básico

¿Quién está conectado?

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