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

Hello,

Im after some help with running one script from within another. Both are CGI files.

In thoery: The first determines if the program has been loaded from command line or web interface. It then gets all the information passed in as parameters and passes those to the second.

What i need to know is:
1) How to run the second script from calling it in the first. (with something like execute->BlastTool.cgi;)
2) Can i pass in all of these variables to the second, and if so do they have to be in reference form or other.

my $blastSeq = ""; # holds the sequence my $blast_filehandle = ""; # file handlers my $ref_filehandle = ""; my $oldRefFile = ""; # old reference file path and name my $species_filter = ""; my $chromo_filter = ""; # filters my @species_filter; my @chromo_filter; my @advanced_filter; my $state; # determines the state of input my $email; ## has email variables been activated my $show_all; # show summary info check box my $show_filter; # show only filtered hits check box # time stamp parameters my $date; my @OrigRef; # arrays of the files my @blastLine; my @refsubjects; # reference to empty array my $refalignment = {}; # builds alignments from reference file my @refelements; # stores the split GI line from reference line my @blast_elements; # stores the split GI line from new blast line my %refList;# holds the accessions from the GI line in ref file my %blastList; # holds the accessions from the GI line in blast file my $boolean; # determines the array to use for the output my @subjects; # stores the whole GI line from blast file my $alignment = {}; # holds alignments from blast file

There is quite a lot......
Any ideas....

cheers,
MonkPaul

Replies are listed 'Best First'.
Re: Executing one script with another
by socketdave (Curate) on Jul 14, 2005 at 16:48 UTC
    I think that you could either use system or exec to call the second program, passing it's parameters on the command line, or you could create a module from the second program, use it and move the outer-most level of logic in the second file into the first... I apologize if I'm missing what you're getting at.
      I looked at system and exec in my book, but it doesnt give a clear way to execute the second perl script.

      Could it be: system(BlastTool(#params here));
      (will look into that though, thanks).

      Also if i use system, as i understand it here, it creates a fork and waits for the son process to finish. Could i therefore implement a loading page also at this stage, and display a "waiting gif" or something whilst it waits for the son process to complete
      (- spiraling off with more and more ideas).

      Cheers, MonkPaul

        You're right about system() waiting for a child process to complete, but exec() works differently. It basically calls the program that you specify and kills the script that's currently running (unless the command can't run, in which case it will return false and put something interesting in $!). Generally I'd use exec() after forking, and use system() when you expect your external command to return in a timely fashion (In fact, system forks then execs and waits for the child to return before giving control back to the script). If you want to display an animated 'waiting' gif or something like it, system() would probably be the one you want.

        In either case, you should enclose your command in quotes or generate an array with your command as the first element and it's arguments as the remaining elements:

        system("/path/to/BlastTool my params here") or die "Could not run command";

        or:
        @command = ("command", "my", "params", "here"); system(@command) or die;
Re: Executing one script with another
by northwind (Hermit) on Jul 14, 2005 at 17:39 UTC
Re: Executing one script with another
by tcf03 (Deacon) on Jul 14, 2005 at 17:03 UTC
    do cgiscript.cgi

    UPDATE - and to use arguments do cgiscript.cgi arg1 arg2

    Makeing the script a module is probably a better way to do it though...

    Good luck

    Ted
    --
    "That which we persist in doing becomes easier, not that the task itself has become easier, but that our ability to perform it has improved."
      --Ralph Waldo Emerson
      do is the right tool, but you can't pass it args that way. Put them in the global @ARGV and the called script will process them as usual. Or make all the variables that are supposed to be shared globals that are declared with our.

      Caution: Contents may have been coded under pressure.
      This looks like a better idea than doing a system(), unless the second cgi isn't a perl script. Of course I'm probably reading too much into the problem...
Re: Executing one script with another
by suaveant (Parson) on Jul 14, 2005 at 17:03 UTC
    One suggestion... if you store the variables you need in a big hash you could do things like iterate over the hash to get all the variables you need. You could then use something like Data::Dumper to serialize the hash and pass it off to the second CGI.

    Ideally, however, I would suggest making the functionality of the second cgi into a library, then you could just call the code from that one directly without executing another script and futzing the data around. If you need them to run in parallel you could use fork.

    Modulizing the second one would ideally be the way to go... otherwise you either have to serialize the data for the second, or pass it all in as parameters... very ugly for large lists.

                    - Ant
                    - Some of my best work - (1 2 3)

Re: Executing one script with another
by blazar (Canon) on Jul 14, 2005 at 17:07 UTC
    It seems that the code you posted only consits of declarations of lexically scoped variables possibly with an assignment. All in all it doesn't shed much light on what you're really after... and maybe it's just me, but the description of what you want to do is at best clumsy. I mean: I understand what you state that you want to do, but I can't see why you should do that. Try explaining, maybe there are more viable alternatives...
      In reply to the previous node........

      Ok,

      I get the data from either command line or WebPage.
      The first script gets the data and passes the information to the next script.
      This is not the only script though. Im trying to modulise the processes so that it wont be just the second sript here, but at least two.
      Im just trying to get this first part going so i can add the other scripts to the second stage.

      At the second stage, dependant on what was entered, either a sequence or two files, the Startup.cgi script will call BlastTool.cgi to run with the two files or run_Remote_Blast.cgi to run with the sequence.

      BlastTool.cgi will then execute a series of other modules that filter results, parse the files data, email data, or a host of other things.

      run_Remote_Blast.cgi will send the sequence to the BLAST web facilities and then return a file, ready for execution with BlastTool.cgi and its filtering and email functions.

      Hows that....

      UPDATE: in total there are around 5 scripts called from BlastTool.cgi. I am also going to implement some output to command line so the user can get output that way, need for a six script.

        Well, in any case I'm not sure this would be the best way to "modulise". How about writing suitable modules instead, each with a consistent interface and require'ing the appropriate one based on the choice you need to do?

        Alternatively I guess you may call the other CGI program passing the relevant data to it with a POST.

        My 2 Eurocents...