r1n0 has asked for the wisdom of the Perl Monks concerning the following question:

I am interested in created a loop that will constantly call an external application (let's just say nmap) to perform work that I don't care to code, but rather than running the application by firing off the application from a shell, I would rather load nmap into a variable name and run it from within the perl script everytime, so it faster than calling the external app. Mostly, I am interested in running bench marks to see what kind of improvement I get from doing something like this, if it is possible.

Any help in this area would be greatly appreciated. Nmap is just a sample, but it gets across my point. After loading the application into the variable, I would like to use options, etc, but I am not sure if this is possible and have never tried such a thing.

Thanks in advance for any help in this area.

-R1n0

Replies are listed 'Best First'.
Re: Load external application to variable
by GrandFather (Saint) on Nov 04, 2008 at 19:38 UTC

    Bottom line: it's probably not practical or useful.

    An operating system is the only thing that can load an application image and do all the work required to run it. Actually loading the image into memory is a small part of the work that goes on to prep an image for running. You may find that running your app out of a RAM disk helps a little - about as much as "loading it into a variable".


    Perl reduces RSI - it saves typing
Re: Load external application to variable
by DStaal (Chaplain) on Nov 04, 2008 at 20:13 UTC

    What you are trying to do isn't possible, really.

    However, if you want to avoid the cost of re-starting an app all the time you might be able to do that. It would depend on what program you are running, but if the program takes it's input from a file, pipe, or standard input, you can start the program and then feed it data as you get it or as needed. (Well, file may or may not work depending on your OS and the program, but the others should work well.)

Re: Load external application to variable
by JavaFan (Canon) on Nov 04, 2008 at 19:35 UTC
    What do you mean by "loading an application into a variable name"? You probably don't mean:
    my $application = "nmap"; my @args = qw !--stylesheet nmap.xsl!; while (1) { system $application, @arg and die; }
      I meant something along the lines of:

      my $application = "nmap";
      my $app_var = undef;

      my $app_options = " -sT -p 80 $IP"; if ( -f $application ){
        open(APP, "<$application");
        binmode APP;
        while( <APP> ){
          $app_var .= $_;
          }
        }

      while{1}{

        #Run application loaded into variable...
        eval { $app_var $app_options };
      }

      It probably makes much better sense to copy the application to ramdisk and just run it from there. Thanks!! I would like to hear anyones' ideas on the subject, though.

      Thanks!

      -R1n0
        It probably makes much better sense to copy the application to ramdisk and just run it from there.

        Any decent operating system already has disk caches (and can use "unused" memory as a disk cache). Why add another layer of complexity trying to subvert that process?

        Well, that would require either writing a kernel module that can run Perl code and do all this from kernel space, or writing a Perl extension that can run binaries.

        Neither seem practical to me; it's a lot of work and I cannot really see much gain.

        But if you pull it off, I'd be very surprised if OSCON rejects your talk proposal. ;-)

Re: Load external application to variable
by sflitman (Hermit) on Nov 06, 2008 at 03:15 UTC
    A completely different approach would be to use my execute code which I reposted here. Basically, it will run a command line application without a shell, so there's less overhead. It also captures the output, so it is 'loading to a variable' which might fit your request better. HTH, SSF.
    sub execute { # execute a command without shell but with timeout my ($cmd,@args)=@_; my $timeout=15; # seconds my ($result,$pid,$i); if ($args[$#args]=~/^--?timeout=(\d+)$/i) { # or pass as last arg $timeout=$1; pop @args; } $i=index($cmd,' '); # args appended to command? if ($i>-1) { unshift @args,split(/\s+/,substr($cmd,$i+1)); # could be more +than one $cmd=substr($cmd,0,$i); } eval { local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required local($/)=undef; alarm $timeout; $pid=open(CMD,'-|',$cmd,@args); # run without shell overhead if ($pid) { $result=<CMD>; close CMD; } else { alarm 0; } alarm 0; }; if ($@) { die $@ unless $@ eq "alarm\n"; # propagate unexpected errors } $result; }