• 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 explorer » 2011-08-20 17:36 @775

Pues entonces, solo tienes que agregar la ruta absoluta a donde se guardan los ficheros.

Por ejemplo. Al usuario se le presenta una serie de nombres de ficheros, de los cuales debe elegir uno. Entonces...
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $file = param('file');      # Nos llega al CGI los nombres de los ficheros
  2. $file = "/ruta/absoluta/al/directorio/del/$file";  # Le ponemos la ruta absoluta
  3.  
  4. # hacemos el resto de operaciones con el $file
Coloreado en 0.004 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

Publicidad

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

Notapor Alfumao » 2011-08-23 03:57 @206

Hola de nuevo.

El problema con la solución que me planteas, es lo que yo pretendo, que el usuario pueda subir archivos a la web para que en ésta se trabaje con ellos (como hace por ejemplo la web de BLAST) y le devuelva unos resultados (en síntesis, se trata de darle a mis CGI un input sobre el que trabajar). Así pues, no puedo ofrecerle esos archivos como predeterminados (que es lo que he entendido que sugieres) sino que he de ser capaz de usar los que el usuario cargue... y aparentemente no me funciona, y no alcanzo a saber porqué.
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-08-23 06:48 @325

Entonces estás usando mal la función param().

param() devuelve las cadenas de texto de las marcas <input> del formulario.

Para recibir el fichero, debes leerte la documentación del módulo CGI, referente al 'upload' de ficheros, en la sección PROCESSING A FILE UPLOAD FIELD.

Este es el código general para resolverlo.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.          $lightweight_fh  = $q->upload('field_name');
  2.  
  3.          # puede devolver un undef si no es un handle de archivo válido
  4.          if (defined $lightweight_fh) {
  5.            # Actualiza el handle a uno compatible con IO::Handle
  6.            my $io_handle = $lightweight_fh->handle;
  7.  
  8.            open (OUTFILE,'>>','/usr/local/web/users/feedback');
  9.            while ($bytesread = $io_handle->read($buffer,1024)) {
  10.              print OUTFILE $buffer;
  11.            }
  12.          }
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Naturalmente, hay que ajustarlo a tus necesidades específicas: nombre del campo del fichero, directorio donde se grabará (el directorio debe tener espacio suficiente y permisos para poder escribir en él), y en vez de 1024 bytes cada vez, se podría aumentar, según lo grandes que sean los ficheros y la memoria disponible (hoy en día, podrías incluso leerte el fichero entero a memoria. Mira el primer hilo indicado abajo).

Una cosa que falta en este código, es un binmode(OUTFILE), para indicar que estamos grabando un fichero en modo binario, si ese es el caso.

Mírate también estos hilos:
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-08-28 15:34 @690

Hola explorer,

He intentado esto pero no me funciona...

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. use IO::Handle;
  6. ###########
  7. #Aqui va el formato de la pagina del CGI
  8. ###########
  9.  
  10. #my $file= param('file');
  11. my $profile= param('profile');
  12. my $dbprofile= param('dbprofile');
  13.  
  14. my $filename= "$$"."$^T"."$file";
  15.  
  16. my $lightweight_fh;
  17. my $io_handle;
  18. my $bytesread;
  19.  
  20. $lightweight_fh  = my $q->upload('file');
  21.  
  22.          # puede devolver un undef si no es un handle de archivo válido
  23.          if (defined $lightweight_fh) {
  24.            # Actualiza el handle a uno compatible con IO::Handle
  25.            $io_handle = $lightweight_fh->handle;
  26.             open (OUTFILE,'>>'.'C:/xampp/htdocs/DB/Uploads/');
  27.             binmode(OUTFILE);
  28.            while ($bytesread = $io_handle->read(my $buffer,2048)) {
  29.              print OUTFILE $buffer;
  30.            }
  31.          }
  32.  
  33. my $resultado = `hmmsearch "$profile" "C:/xampp/htdocs/DB/Uploads/$filename" > C:/xampp/htdocs/DB/$filename.out`;
  34.  
  35. my $report= "C:/xampp/htdocs/DB/$filename.out";
  36.  
  37. print qq(<A HREF='$report' TARGET='_blank'>-Open in browser or Right click to download file-</A><br><br><br><br><br>\n);
  38.  
Coloreado en 0.002 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 explorer » 2011-08-29 12:05 @545

La función my() está mal puesta, en la línea 20.

Prueba con

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $lightweight_fh  = upload('file');
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-08-29 15:04 @669

Hola explorer,

el código funcional es este,

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. use IO::Handle;
  6.  
  7. my $file= param('file');
  8. my $profile= param('profile');
  9. my $dbprofile= param('dbprofile');
  10.  
  11. my $filename= "$$"."$^T"."$file";
  12.  
  13. my $lightweight_fh;
  14. my $io_handle;
  15. my $bytesread;
  16.  
  17. $lightweight_fh  = upload('file');
  18.  
  19.          if (defined $lightweight_fh) {
  20.             $io_handle = $lightweight_fh->handle;
  21.             open (OUTFILE,'>>'.'C:/xampp/htdocs/DB/Uploads/secuencia.txt'); #problema interpolacion de variable,  para que funcione he de poner un nombre al final de la ruta, no sirve una variable tipo escalar ($)
  22.             binmode(OUTFILE);
  23.            while ($bytesread = $io_handle->read(my $buffer,2048)) {
  24.              print OUTFILE $buffer;
  25.            }
  26.          }
  27.  
  28. my $resultado = `hmmsearch "$profile" "C:/xampp/htdocs/DB/Uploads/secuencia.txt" > C:/xampp/htdocs/DB/$filename.out`;
  29.  
  30. my $report= 'C:/xampp/htdocs/DB/$filename.out'; #problema interpolacion igual que el caso anterior, si pongo $filename.out , no me sale resultado (pasa igual si va entre comillas " " ó ' ').
  31.  
  32. print qq(<A HREF='$report' TARGET='_blank'>-Open in browser or Right click to download file-</A><br><br><br><br><br>\n);
  33.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4



Pero tengo un problema con la interpolación de la variable al final de las rutas de archivo(marcado en código):
- Al abrir el archivo SALIDA (OUTFILE)
- En la ruta de la variable $report.

Si intento la interpolación en alguno de los casos, no obtengo resultado válido.

Y otra pregunta, ¿hay alguna forma de borrar el archivo OUTFILE una vez leído el resultado?
Última edición por Alfumao el 2011-09-27 16:33 @731, editado 2 veces 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-08-29 15:10 @673

Cuando, dentro de una cadena de caracteres, exista una variable que quieras que se interpole su valor, debes usar comillas dobles:

"C:/xampp/htdocs/FUNGALOXPHOS_CSS/$filename.out"

Si usas comillas simples, estás indicando una cadena literal, una ruta a un nombre de fichero que se llama '$filename.out' (dolar, 'filename', punto, 'out').

Para borrar archivos, puedes usar la instrucción unlink():

unlink 'C:/xampp/htdocs/DB/Uploads/secuencia.txt';
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-08-29 15:49 @700

Muchas gracias, explorer,

Solucionado el problema de las interpolaciones.

Eso sí, no logro borrar el archivo que se genera con unlink().

Te dejo una muestra del código funcional por completo excepto la parte de unlink().

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


Por cierto, cada vez que efectúo la operación del CGI, me aparecen unos archivos llamados CGItemp+"numero aleatorio" (parecen archivos temporales que usa el CGI para su ejecución, uno deriva de "$profile" y otro de "C:/xampp/htdocs/DB/Uploads/$filename.txt") que me llenan la carpeta de la DB... y tampoco sé cómo borrarlos.
Última edición por Alfumao el 2011-09-27 16:34 @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-08-29 19:14 @843

unlink() no genera ficheros, los borra.

En la línea 34 vuelves a cometer el mismo error de antes: estás usando comillas simples, con lo que impides la interpolación de la variable $filename.

En la línea 33, escribes CLOSE, pero en realidad es close (en minúsculas).

La línea 33 (el close()) debería estar puesta entre la 26 y la 27. De hecho, todas las instrucciones de las líneas 29 a 34 deberían estar metidas dentro del if() de la línea 20 (ejecutar todo el código si el usuario nos ha pasado un fichero y podemos leerlo).

Los ficheros temporales CGItemp es donde el módulo CGI guarda, temporalmente, el fichero que ha mandado el usuario, esperando que lo leamos con el bucle while() de la línea 24. Por defecto, CGI borrará el fichero, al final del programa (salvo que el programa termine con errores).

Esto puede parecer un poco raro: el módulo CGI graba el fichero subido por el usuario en un fichero temporal. Y luego nosotros lo leemos, escribiendo una copia a otro fichero, ya con nuestro nombre. Lo ideal, en muchos casos, es que pudiéramos procesar, directamente, el fichero temporal. Eso se consigue con la función tmpFileName($file);. De esta manera, nos ahorramos todo el trabajo de open(), while() y close() (más información en la documentación de CGI.pm, sección PROCESSING A FILE UPLOAD FIELD).

Pero bueno, lo normal es hacerlo así, con una copia privada nuestra.
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 09:04 @419

Hola explorer,

He seguido tus recomendaciones y ha funcionado, eso sí, el temporal lo sigue creando y dejándolo en la carpeta principal (C:/xampp/htdocs/DB/).

Aquí está el código con tus correcciones incorporadas.

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


Muchas gracias una vez más, explorer.
Alfumao
Perlero nuevo
Perlero nuevo
 
Mensajes: 178
Registrado: 2009-12-10 11:20 @514

AnteriorSiguiente

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron