Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Perl interact with the scripts it is running?

I have a Perl script that runs a different utility (called Radmind, for those interested) that has the capability to edit the filesystem. The Perl script monitors output from this process, so it would be running throughout this whole situation.

What would happen if the utility being run by the script tried to edit the script file itself, that is, replace it with a newer version? Does Perl load the script and any linked libraries at the start of its execution and then ignore the script file itself unless told specifically to mess with it? Or perhaps, would all hell break loose, and executions might or might not fail depending on how the new file differed from the one being run?

Or maybe something else entirely? Apologies if this belongs on SuperUser—seems like a gray area to me.

like image 980
NReilingh Avatar asked Sep 01 '10 12:09

NReilingh


3 Answers

It's not quite as simple as pavel's answer states, because Perl doesn't actually have a clean division of "first you compile the source, then you run the compiled code"[1], but the basic point stands: Each source file is read from disk in its entirety before any code in that file is compiled or executed and any subsequent changes to the source file will have no effect on the running program unless you specifically instruct perl to re-load the file and execute the new version's code[2].

[1] BEGIN blocks will run code during compilation, while commands such as eval and require will compile additional code at run-time

[2] Most likely by using eval or do, since require and use check whether the file has been loaded already and ignore it if it has.

like image 72
Dave Sherohman Avatar answered Nov 03 '22 01:11

Dave Sherohman


For a fun demonstration, consider

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

Sample run:

$ ./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!
like image 29
Greg Bacon Avatar answered Nov 02 '22 23:11

Greg Bacon


Your Perl script will be compiled first, then run; so changing your script while it runs won't change the running compiled code.

Consider this example:

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

and watch the result when run multiple times.

like image 44
pavel Avatar answered Nov 03 '22 01:11

pavel