• Publicidad

Generar un script en Bash desde un script en Perl

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

Generar un script en Bash desde un script en Perl

Notapor DieFeM » 2012-08-07 02:40 @152

Hola a todos.

Estoy tratando de generar un script en Bash desde un script en Perl a partir de una variable que contiene las líneas de dicho script.

El problema viene al ejecutar el script, me salen errores con el retorno de carro (\r).

El contenido de la variable podría ser cualquier script en Bash que se recoje desde una base de datos MySQL, de una columna TEXT, y que se ha escrito y subido a la base de datos desde un formulario HTML con <textarea>.

El contenido de la variable podría ser algo similar a:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $postcmd = 'mkdir backup
  2.                cp service.log backup/service.log';
  3.  
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4



y el código para crear el archivo Bash es el siguiente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.         my (@postcmdlines) = $postcmd;
  2.        
  3.         open FILE, ">>postinstall.sh";
  4.         foreach my $postcmdline ( @postcmdlines )
  5.         {
  6.                 print FILE $postcmdline;
  7.         }
  8.         close FILE;
  9.         chmod 0755, 'postinstall.sh';
  10.         system('./postinstall.sh');
  11.         unlink "postinstall.sh";
  12.  
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4


El problema es que la salida de system() me da error porque al final de cada comando, en algun momento, se le añade un retorno de carro, y no sé cómo solucionarlo. Llevo varias horas y he probado muchas y diferentes tecnicas que he leido por ahí, pero no encuentro nada que funcione.

La salida de Perl sería esta:

cp: no se puede crear el fichero regular «backup/service.log\r»: No existe el fichero o el directorio

Aparte de que la carpeta que se crea parece llamarse backup pero en realidad se llama backup\r, pero esto no lo muestra como un error.

De antemano, muchas gracias.
DieFeM
Perlero Nuevo
Perlero Nuevo
 
Mensajes: 3
Registrado: 2012-08-07 02:10 @132

Publicidad

Re: Generar un script en Bash desde un script en Perl

Notapor explorer » 2012-08-07 06:13 @301

Bienvenido a los foros de Perl en Español, DieFeM.

Primero, advertir a los demás que las técnicas aquí descritas son las que utilizan los hackers y delincuentes para poder ejecutar código remoto de forma fraudulenta, por lo que deben repasar su legislación local para comprobar si pueden aplicarlas en sus respectivos países.

Algo que debes resolver primero es saber qué retorno de carro es el del sistema en donde vas a ejecutarlo. No es lo mismo Mac, Windows o Linux/UNIX. Cada uno de ellos tiene su propio marcador de fin de línea.

Solo por poner "\r" estás indicando el carácter "retorno de carro", pero ese es el marcado de fin de línea en el caso de los sistemas Mac. En Perl, si usas "\n" dentro de un programa, estarás aludiendo al fin de línea del sistema operativo en que se esté ejecutando ese programa, sea el que sea.

El código que muestras tiene alguna falla...

La línea 1 no hace lo que pretendes: quieres asignar cada línea contenido dentro de $postcmd a cada elemento de @postcmdlines, pero en realidad solo estás almacenando todo el comando en el primer elemento del array.

En la línea 3 estás abriendo postinstall.sh en modo 'agregar', que no sé si es lo que realmente quieres hacer. ¿No será simplemente en modo 'escritura'?

En la línea 4 haces un bucle por los elementos de @postcmdlines, pero ya sabemos que solo hay un elemento, así que el bucle, sobra.

El programa se podría escribir así (no probado):
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $cmdfile = 'postinstall.sh';
  2. open  FILE, '>', $cmdfile;
  3. print FILE "#!/bin/bash\n";
  4. print FILE "$postcmdline\n";
  5. close FILE;
  6. chmod 0755, $cmdfile;
  7. system('/bin/bash', $cmdfile);
  8. unlink $cmdfile;
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4


En tu caso, lo que podrías hacer también es dividir el comando leído desde la base de datos con el comando split(), y entonces ya lo puedes asignar al array, y luego grabarlo en el archivo con el bucle for(). Pero para esto, necesitas darle a split() un delimitador así: /[\r\n]+/. Quedaría:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my @postcmdlines = split /[\r\n]+/, $postcmd;
  2. my $cmdfile = 'postinstall.sh';
  3. open  FILE, '>', $cmdfile;
  4. print FILE "#!/bin/bash\n";
  5. for my $line (@postcmdlines) {
  6.     print FILE "$line\n";
  7. }
  8. close FILE;
  9. chmod 0755, $cmdfile;
  10. system('/bin/bash', $cmdfile);
  11. unlink $cmdfile;
Coloreado en 0.006 segundos, usando GeSHi 1.0.8.4
Lo que realmente estamos haciendo es partir el comando original, compuesto por cualquier combinación de caracteres de fin de línea, y recreando un comando con los caracteres de fin de línea del sistema en donde estamos ejecutando el programa.

Pero... tampoco necesitas hacer nada de eso...

En los Bash modernos existe la opción '-c', que permite pasarle un programa entero a Bash desde una cadena. O usando la opción '-s' se pueden pasar los comandos por la entrada estándar.

Así que de esta manera, puedes ejecutar cosas en Bash sin ni siquiera grabar ningún postinstall.sh en el sistema de archivos...

Ejemplo: cómo enviar un correo electrónico
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $asunto = 'Asunto especial';
  2. my $email  = 'email@del_destinatario.com';
  3. my $texto  = 'Un texto que queremos enviar';
  4.  
  5. system('/bin/bash', '-c', qq(mail -s "$asunto" $email <<< "$texto"));
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4
En tu caso, yo lo haría con la opción '-s', enviando el comando por la entrada estándar de /bin/bash.
JF^D Perl Programming Language
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 12611
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Generar un script en Bash desde un script en Perl

Notapor DieFeM » 2012-08-07 06:38 @318

Muchísimas gracias, lo había resuelto y al parecer funcionaba de casualidad, pero voy a probar lo que me indicas, eso creo que va a ser lo mejor, así no necesito que se guarde ningún archivo.

Lo que yo había hecho era simplemente quitar todos los "\r" usando $cmdlines=~ s/\r//g;, con un bucle un poco distinto, con for en lugar de foreach, que de nada sirve :).

El fin de este software es un panel de control de servidores de juegos de código abierto llamado opengamepanel en el que estoy colaborando y lo que me gustaría es ejecutar una serie de comandos personalizados antes y después de la instalación del servidor, los cuales se especifican en la configuración, por juego o por servidor, desde el panel de control web a la aplicación remota en Perl.

Esta aplicación se ejecuta tanto en Linux como en Windows, pero en Windows se ejecuta sobre una plataforma llamada Cygwin que usa Bash y creo que, aun en Windows, éste usa "\n" como salto de línea y retorno de carro. Tampoco estoy seguro.

Me pregunto si a modo de script no tendrá algunas ventajas más que de modo directo, como por ejemplo declarar funciones, ¿estoy en lo cierto?

Gracias de nuevo.
DieFeM
Perlero Nuevo
Perlero Nuevo
 
Mensajes: 3
Registrado: 2012-08-07 02:10 @132

Re: Generar un script en Bash desde un script en Perl

Notapor explorer » 2012-08-07 07:20 @347

DieFeM escribiste:Lo que yo había hecho era simplemente quitar todos los "\r" usando $cmdlines=~ s/\r//g;
Es que a lo mejor el comando que llega desde el formulario web sí tiene esos caracteres en el final de línea, así que mejor, quitarlos.

DieFeM escribiste:con un bucle un poco distinto, con for en lugar de foreach, que de nada sirve :)
En Perl, un bucle for() es lo mismo que un foreach() (bueno, 4 letras menos).

DieFeM escribiste:Me pregunto si a modo de script no tendrá algunas ventajas más que de modo directo, como por ejemplo declarar funciones, ¿estoy en lo cierto?
Yo creo que Bash le dará igual... :)
JF^D Perl Programming Language
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 12611
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Generar un script en Bash desde un script en Perl

Notapor DieFeM » 2012-08-07 08:03 @377

Al final he optado por hacer 3 scripts, ya que funciona tan bien...

Uno con la preinstalación, otro con la postinstalación y un tercero que carga primero la preinstalacion, luego ejecuta la instalación y con un wait ${!} espera a que termine para lanzar la postinstalación.

¡Gracias a tu ayuda he conseguido que vaya justo como yo quería! ¡PE, E, ERRE, fectoo! :mrgreen:

Muchísimas gracias.
DieFeM
Perlero Nuevo
Perlero Nuevo
 
Mensajes: 3
Registrado: 2012-08-07 02:10 @132


Volver a Básico

¿Quién está conectado?

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