2010-09-01 9 views
5

Ich habe ein Perl-Skript, das ein anderes Dienstprogramm (mit dem Namen Radmind, für diejenigen, die interessiert sind), die die Fähigkeit zum Bearbeiten des Dateisystems hat. Das Perl-Skript überwacht die Ausgabe dieses Prozesses, sodass es während der gesamten Situation ausgeführt wird.Wie interagiert Perl mit den Skripten, die es ausführt?

Was würde passieren, wenn das Dienstprogramm, das vom Skript ausgeführt wird, versucht, die Skriptdatei selbst zu bearbeiten, dh sie durch eine neuere Version zu ersetzen? Lädt Perl das Skript und alle verknüpften Bibliotheken zu Beginn seiner Ausführung und ignoriert dann die Skriptdatei selbst, sofern nicht speziell darauf hingewiesen wird, dass sie damit umgehen? Oder vielleicht, würde die Hölle losbrechen, und die Ausführungen könnten oder könnten nicht scheitern, je nachdem, wie sich die neue Datei von der ausgeführten Datei unterscheidet?

Oder vielleicht etwas ganz anderes? Entschuldigung wenn das auf SuperUser — gehört scheint mir eine Grauzone.

Antwort

6

Es ist durchaus nicht ist so einfach wie Antwort Staaten der pavel, weil Perl eigentlich eine saubere Trennung nicht von dem, "Zuerst kompilieren Sie die Quelle, dann führen Sie den kompilierten Code aus" [1], aber der grundlegende Punkt lautet: Jede Quelldatei wird vollständig von der Festplatte gelesen, bevor ein Code in dieser Datei kompiliert oder ausgeführt wird und alle nachfolgenden Änderungen an der Quelle fi le hat keine Auswirkung auf das laufende Programm, es sei denn, Sie weisen perl an, die Datei neu zu laden und den Code der neuen Version auszuführen [2].

[1] BEGIN Blöcke Code während der Kompilierung ausgeführt werden, während Befehle wie eval und require zusätzlichen Code zur Laufzeit kompiliert

[2] Höchstwahrscheinlich durch eval oder do, da require und use Prüfung mit ob die Datei bereits geladen wurde und sie ignoriert, falls dies der Fall ist.

+1

Es ist nicht einmal so einfach wie Ihre Antwort, Sie können den Code an das Ende Ihrer Datei in einem 'BEGIN'-Block anhängen und es wird in das Programm aufgenommen. In mindestens der Version von Perl, auf die ich im Moment Zugriff habe, liest sie nicht die ganze Datei, bevor sie mit der Analyse beginnt, und 'BEGIN'-Blöcke werden ausgeführt, sobald die schließende geschweifte Klammer geparst wird. Dieses Verhalten ist wahrscheinlich sehr vom Betriebssystem abhängig. –

0

Die Skriptdatei wird einmal in den Speicher gelesen. Sie können die Datei danach von einem anderen Dienstprogramm aus bearbeiten - oder aus dem Perl-Skript selbst - wenn Sie möchten.

2

Ihr Perl-Skript wird zuerst kompiliert und dann ausgeführt; Wenn Sie also das Skript während der Ausführung ändern, wird der ausgeführte kompilierte Code nicht geändert.

Betrachten Sie dieses Beispiel:

#!/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"; 

und das Ergebnis sehen, wenn mehrere Male ausgeführt.

+0

Sie wollen 'while (<>)' – flies

3

Für einen Spaß Demonstration betrachten

#! /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"; 
} 

Probelauf:

$ ./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

Wie die anderen sagten, wird das Skript in den Speicher eingelesen, kompiliert und ausgeführt. GBacon zeigt, dass Sie die Datei löschen können und es wird ausgeführt. Dieser Code unten zeigt, dass Sie die Datei und do ändern können und das neue Verhalten erhalten.

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

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

... TUN SIE DIESES NICHT !!!

0

Perl-Skripte sind einfache Textdateien, die in den Arbeitsspeicher gelesen, im Arbeitsspeicher kompiliert werden, und das Textdateiskript wird nicht erneut gelesen. (Ausnahmen sind Module, die nach der Kompilierung in den lexikalischen Geltungsbereich kommen und in einigen Fällen do und eval Anweisungen ...)

Es gibt ein bekanntes Dienstprogramm, das dieses Verhalten ausnutzt. Sehen Sie sich CPAN und seine vielen Versionen an, die sich wahrscheinlich in Ihrem Verzeichnis/usr/bin befinden. Es gibt eine CPAN-Version für jede Perl-Version auf Ihrem System. CPAN erkennt, wenn eine neue Version von CPAN selbst verfügbar ist, fragen Sie, ob Sie es installieren möchten, und wenn Sie "y" sagen, wird die neuere Version heruntergeladen und respawnen Sie dort, wo Sie aufgehört haben, ohne irgendwelche Daten zu verlieren.

Die Logik ist nicht schwer zu folgen. Lesen Sie/usr/bin/CPAN und folgen Sie dann den individualisierten Versionen, die sich auf das beziehen, was $ Config :: Config {version} auf Ihrem System erzeugen würde.

Prost.

Verwandte Themen