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):
Using perl Syntax Highlighting
my $cmdfile = 'postinstall.sh';
open FILE, '>', $cmdfile;
print FILE "#!/bin/bash\n";
print FILE "$postcmdline\n";
close FILE;
chmod 0755, $cmdfile;
system('/bin/bash', $cmdfile);
unlink $cmdfile;
Coloreado en 0.001 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:
Using perl Syntax Highlighting
my @postcmdlines = split /[\r\n]+/, $postcmd;
my $cmdfile = 'postinstall.sh';
open FILE, '>', $cmdfile;
print FILE "#!/bin/bash\n";
for my $line (@postcmdlines) {
print FILE "$line\n";
}
close FILE;
chmod 0755, $cmdfile;
system('/bin/bash', $cmdfile);
unlink $cmdfile;
Coloreado en 0.001 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
Using perl Syntax Highlighting
my $asunto = 'Asunto especial';
my $email = 'email@del_destinatario.com';
my $texto = 'Un texto que queremos enviar';
system('/bin/bash', '-c', qq(mail -s "$asunto" $email <<< "$texto"));
Coloreado en 0.001 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.