2010-09-01 3 views
5

У меня есть скрипт Perl, который запускает другую утилиту (так называемый Radmind, для тех, кто интересуется), который имеет возможность редактировать файловую систему. Perl-скрипт контролирует вывод из этого процесса, поэтому он будет работать в этой ситуации.Как Perl взаимодействует со скриптами, которые он запускает?

Что произойдет, если утилита, запускаемая скриптом, попытается отредактировать сам файл сценария, то есть заменить его более новой версией? Перл загружает скрипт и любые связанные библиотеки в начале его выполнения, а затем игнорирует сам файл сценария, если только он специально не связывается с ним? Или, может быть, все ад разрывается, и выполнение может или не может потерпеть неудачу в зависимости от того, как новый файл отличается от того, который выполняется?

Возможно, что-то еще совсем? Извинения, если это принадлежит SuperUser —, кажется мне серым.

ответ

6

Это не совсем так просто, как состояния ответа ПАВЛА, потому что Perl фактически не имеет чистое разделение «Сначала вы скомпилируете источник, затем запустите скомпилированный код» [1], но основная точка стоит: каждый исходный файл полностью считывается с диска, прежде чем компилируется или выполняется какой-либо код в этом файле, и любые последующие изменения в источник fi le не повлияет на запущенную программу, если вы специально не указали perl, чтобы перезагрузить файл и выполнить код новой версии [2].

[1] BEGIN блоки будут работать код во время компиляции, в то время как команды, такие как eval и require будет собирать дополнительный код во время выполнения

[2] Скорее всего, используя eval или do, так как require и use проверки был ли файл уже загружен и проигнорировать его, если он есть.

+1

Это не так просто, как ваш ответ, вы можете добавить код в конец вашего файла в блоке 'BEGIN', и он будет включен в программу. По крайней мере, в версии perl, к которой у меня есть доступ, на данный момент он не будет читать весь файл, прежде чем приступать к его синтаксическому анализу, а блоки BEGIN будут выполняться сразу же после разбора закрывающей фигурной скобки. Такое поведение, скорее всего, зависит от ОС. –

0

Файл сценария читается один раз в памяти. После этого вы можете отредактировать файл из другой утилиты - или из самого скрипта Perl - если хотите.

2

Сначала будет скомпилирован ваш скрипт Perl, затем запустите; поэтому изменение сценария во время его запуска не изменит исполняемый скомпилированный код.

Рассмотрим следующий пример:

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

и смотреть результат при запуске несколько раз.

+0

Вы хотите 'while (<>)' – flies

3

Для веселья демонстрации, рассмотрит

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

Пример запуск:

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

Как говорили другие, скрипт считывается в память, компилируется и запускается. GBacon показывает, что вы можете удалить файл, и он будет запущен. Этот код ниже показывает, что вы можете изменить файл и do и получить новое поведение.

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

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

... НЕ ДЕЛАЙТЕ ЭТО !!!

0

Perl-скрипты - это простые текстовые файлы, которые считываются в память, скомпилированы в память, а скрипт текстового файла не читается снова. (Исключения - это модули, которые после компиляции входят в лексическую область и do и eval в некоторых случаях ...)

Существует известная утилита, которая использует это поведение. Посмотрите на CPAN и его многочисленные версии, которые, вероятно, находятся в каталоге/usr/bin. Для каждой версии Perl в вашей системе есть версия CPAN. CPAN почувствует, когда доступна новая версия CPAN, спросите, хотите ли вы ее установить, и, если вы скажете «y», она загрузит новую версию и сама респауна, где вы остановились, не потеряв никаких данных.

Логику этого выполнить не сложно. Прочтите/usr/bin/CPAN, а затем следуйте индивидуальным версиям, связанным с тем, что в вашей системе будет генерироваться $ Config :: Config {version}.

Cheers.

Смежные вопросы