2010-09-01 12 views
5

Tengo un script Perl que ejecuta una utilidad diferente (llamada Radmind, para aquellos interesados) que tiene la capacidad de editar el sistema de archivos. La secuencia de comandos de Perl supervisa la salida de este proceso, por lo que se ejecutará a lo largo de toda esta situación.¿Cómo interactúa Perl con los scripts que está ejecutando?

¿Qué pasaría si la utilidad que ejecuta el script intentara editar el archivo de script, es decir, reemplazarlo por una versión más nueva? ¿Perl carga la secuencia de comandos y las bibliotecas vinculadas al inicio de su ejecución y luego ignora el archivo de la secuencia de comandos a menos que se le indique específicamente que se meta con él? O tal vez, ¿se desataría el infierno y las ejecuciones podrían fallar o no dependiendo de cómo difiera el nuevo archivo del que se está ejecutando?

¿O tal vez algo completamente diferente? Disculpas si esto pertenece en SuperUser — me parece un área gris.

Respuesta

6

No es bastante tan simple como estados de respuesta de Pavel, porque Perl no tiene realmente una división limpia de "primero compila la fuente, luego ejecuta el código compilado" [1], pero el punto básico permanece: cada archivo fuente se lee del disco en su totalidad antes de compilar o ejecutar cualquier código en ese archivo y cualquier cambio posterior en el archivo fuente fi no tendrá ningún efecto en el programa en ejecución a menos que instruya específicamente perl para volver a cargar el archivo y ejecutar el código de la nueva versión [2].

[1] BEGIN bloques se ejecutará código durante la compilación, mientras que los comandos tales como eval y require se compilar código adicional en tiempo de ejecución

[2] Lo más probable es mediante el uso de eval o do, ya require y use cheque si el archivo ya se ha cargado e ignórelo si lo tiene.

+1

Ni siquiera es tan simple como su respuesta, puede agregar el código al final de su archivo en un bloque 'BEGIN' y se incluirá en el programa. En al menos la versión de perl a la que tengo acceso en este momento no leerá todo el archivo antes de comenzar a analizarlo, y los bloques 'BEGIN' se ejecutarán tan pronto como se analice el parche de cierre. Este comportamiento es muy dependiente del sistema operativo. –

0

El archivo de script se lee una vez en la memoria. Después de eso, puede editar el archivo desde otra utilidad, o desde el script de Perl, si lo desea.

2

Su script de Perl se compilará primero y luego se ejecutará; por lo tanto, cambiar el script mientras se ejecuta no cambiará el código compilado en ejecución.

Considere este ejemplo:

#!/usr/bin/perl 

use strict; 
use warnings; 

push @ARGV, $0; 
$^I = ''; 

my $foo = 42; 
my $bar = 56; 

my %switch = (
    foo => 'bar', 
    bar => 'foo', 
); 

while (<ARGV>) { 
    s/my \$(foo|bar)/my \$$switch{$1}/; 
    print; 
} 

print "\$foo: $foo, \$bar: $bar\n"; 

y ver el resultado cuando se ejecuta varias veces.

+0

desea 'while (<>)' – flies

3

Para una demostración diversión, considere

#! /usr/bin/perl 

die "$0: where am I?\n" unless -e $0; 

unlink $0 or die "$0: unlink $0: $!\n"; 

print "$0: deleted!\n"; 
for (1 .. 5) { 
    sleep 1; 
    print "$0: still running!\n"; 
} 

de ejecución de la muestra:

$ ./prog.pl 
./prog.pl: deleted! 
./prog.pl: still running! 
./prog.pl: still running! 
./prog.pl: still running! 
./prog.pl: still running! 
./prog.pl: still running!
0

Como dijeron los demás, la secuencia de comandos se lee en la memoria, se compila y se ejecuta. GBacon muestra que puede eliminar el archivo y se ejecutará. Este código a continuación muestra que puede cambiar el archivo y do y obtener el nuevo comportamiento.

use strict; 
use warnings; 
use English qw<$PROGRAM_NAME>; 

open my $ph, '>', $PROGRAM_NAME; 
print $ph q[print "!!!!!!\n";]; 
close $ph; 
do $PROGRAM_NAME; 

... ¡NO HAGA ESTO!

0

Los scripts Perl son archivos de texto simples que se leen en la memoria, se compilan en la memoria y el script del archivo de texto no se vuelve a leer. (Las excepciones son módulos que entran en el alcance léxico después de la compilación y las sentencias do y eval en algunos casos ...)

Existe una utilidad conocida que explota este comportamiento. Mire el CPAN y sus muchas versiones que probablemente estén en su directorio/usr/bin. Hay una versión de CPAN para cada versión de Perl en su sistema. CPAN detectará cuándo está disponible una nueva versión de CPAN, preguntará si desea instalarla y, si dice "y", descargará la versión más nueva y se reagrupará justo donde la dejó sin perder ningún dato.

La lógica de esto no es difícil de seguir. Lea/usr/bin/CPAN y luego siga las versiones individualizadas relacionadas con lo que $ Config :: Config {versión} generaría en su sistema.

Saludos.

Cuestiones relacionadas