我有一个Perl脚本,它运行一个不同的实用程序(对于那些感兴趣的人来说,称为Radmind),它具有编辑文件系统的能力。 Perl脚本监视此进程的输出,因此它将在整个情况下运行。
如果脚本运行的实用程序试图编辑脚本文件本身,即将其替换为较新版本,会发生什么? Perl是否在执行开始时加载脚本和任何链接库,然后忽略脚本文件本身,除非特别说明要搞乱它?或许,一切都会破裂,执行可能会或可能不会失败,具体取决于新文件与正在运行的文件有何不同?
或者其他可能完全不同?如果这属于SuperUser而道歉 - 对我来说似乎是个灰色区域。
答案 0 :(得分:7)
它不像perl
重新加载文件并执行新版本的代码[2]。
[1] BEGIN
块将在编译期间运行代码,而eval
和require
等命令将在运行时编译其他代码
[2]最有可能使用eval
或do
,因为require
和use
检查文件是否已经加载,如果文件已经加载则忽略它。< / p>
答案 1 :(得分: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!
答案 2 :(得分: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";
并在多次运行时观察结果。
答案 3 :(得分:0)
脚本文件一次读入内存。您可以在此之后从其他实用程序编辑文件 - 或者从Perl脚本本身编辑 - 如果您愿意的话。
答案 4 :(得分: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;
......不要这样做!!!
答案 5 :(得分:0)
Perl脚本是简单的文本文件,它们被读入内存,在内存中编译,并且不再读取文本文件脚本。 (例外是在编译后进入词法范围的模块以及在某些情况下do
和eval
语句......)
有一个众所周知的实用程序可以利用这种行为。查看CPAN及其许多版本,这些版本可能位于/ usr / bin目录中。您系统上的每个Perl版本都有一个CPAN版本。 CPAN将感知CPAN本身的新版本何时可用,询问您是否要安装它,如果您说“y”,它将下载较新版本并在您停止的地方重新生成,而不会丢失任何数据。
这个逻辑并不难理解。阅读/ usr / bin / CPAN,然后按照与$ Config :: Config {version}在您的系统上生成的相关的个性化版本。
干杯。