Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Running perl script from a perl script

by ikuzmanovs (Novice)
on Jan 08, 2010 at 16:33 UTC ( [id://816345]=perlquestion: print w/replies, xml ) Need Help??

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

Hi, I have a series of perl script each dependent on the output of the previous, some of them with command line arguments. Is there a way for this to be done in Perl so that I run the whole pipeline from one single program, keeping track of all the right imput and output files and the right command line arguments (for ex. the output of the 1st program is the command line argument of the second or sth. like that)

I have read about several ways of calling a shell command from within a perl script (system command, backticks, exec..)I tried them on a very simple program but they do not really work as I want to.

I have a program "success.pl" which only prints "Success" on the screen and another program called "program.pl" from within which I try to execute the program success.pl. I tried the following:


1. backticks
@var=`success.pl`; print @var;

Nothing is printed on the screen :(

2.system

@var=system("success.pl") or die "cant run"; print @var;
I get -1

3.open

OPEN(FH, "success.pl"); @var=<FH>; close(FH); print $var;
I get: Undefined subroutine &main::OPEN called at program.pl line 3 :(

4.exec

@var=exec ("success.pl") or die "cant run"; print @var;
I get 0
Help please!!! Thanks, Irena

Replies are listed 'Best First'.
Re: Running perl script from a perl script
by afoken (Chancellor) on Jan 08, 2010 at 16:46 UTC
    • 1 - script is not executable. Try chmod +x success.pl on Unix. On windows, you need to invoke scripts via perl.exe (from $^X)
    • 2 - system does not capture output
    • 3 - There is no OPEN function. Did you mean open? Probably not. You would read the contents of success.pl, but not execute it.
    • 4 - like system, exec does not capture output, and it replaces the current process with another process. You will never reach the following print statement. Either exec() fails and die terminates your script, or exec() is successful and replaces the process with your script with the new process running success.pl.

    You should really start reading the perl documentation. You might be interested in do, require, perlmod.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: Running perl script from a perl script
by kennethk (Abbot) on Jan 08, 2010 at 16:44 UTC

    First off, a potentially easier solution in a long-term sense may be to migrate the scripts you are calling into modules. This is of course not the question you asked, but something to consider.

    Another possibility is reading in your script and using do to execute the code. See How to read code from file and execute it in loop ?.

    Since you are trying to capture the output from another process, backticks should do what you want. It returns a string, so you should be assigning it to a scalar, but that should not have interfered with your syntax. Are you sure your success.pl script outputs to STDOUT? I suspect it's actually writing to STDERR, which still gets output to the screen on normal execution but is not captured by backticks. What happens when you try again, this time redirecting STDERR to STDOUT:

    my $var = `success.pl 2>&1`; print $var;

    Update: This, of course, only works if you can run that command on the command line, i.e. your script is set executable. Otherwise, you should type:

    my $var = `perl success.pl 2>&1`; print $var;

    See Quote Like Operators.

Re: Running perl script from a perl script
by zentara (Archbishop) on Jan 08, 2010 at 17:02 UTC
    Try these:
    #!/usr/bin/perl use warnings; use strict; use IPC::Open3; my $pid = open3(\*WRITE, \*READ, 0,"success.pl"); #if \*ERROR is false, STDERR is sent to STDOUT #get the answer chomp(my $answer = <READ>); print "query = $answer\n"; waitpid($pid, 1); # It is important to waitpid on your child process, # otherwise zombies could be created.

    ....or run a command interpreter like bash, and print commands to it

    #!/usr/bin/perl use warnings; use strict; use IPC::Open3; $|=1; #my $pid=open3(\*IN,\*OUT,\*ERR,'/bin/bash'); my $pid=open3(\*IN,\*OUT,0,'/bin/bash'); # set \*ERR to 0 to send STDERR to STDOUT my $cmd = 'date'; #send cmd to bash print IN "$cmd\n"; my $result = <OUT>; print $result;

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku
Re: Running perl script from a perl script
by jettero (Monsignor) on Jan 08, 2010 at 16:37 UTC
    When I want to fork a new perl, I tend to use IPC::System::Simple and systemx($^X, $program_file).

    Normally you would NOT want to do this though. Perl can just run more perl — see do.

    -Paul

Re: Running perl script from a perl script
by jffry (Hermit) on Jan 08, 2010 at 17:58 UTC

    Maybe the reason backticks didn't work is because you are on Unix and "." is not in your path. This works.

    $ ./2.pl Hello $ cat 1.pl #!/usr/bin/perl print "Hello\n"; $ cat 2.pl #!/usr/bin/perl my $output = `./1.pl`; print $output;

    EDIT: Not having "." in your PATH on a Unix box also explains the -1 return code you got from system(). The shell could not find the success.pl executable in your PATH.

Re: Running perl scrit from a perl script
by ww (Archbishop) on Jan 08, 2010 at 21:50 UTC

    Were I to guess you're running W32:

    #!/usr/bin/perl print "Success Ran Here"; =head path\to\success>perl -e "@var=`success.pl`;print @var;\n" Success Ran Here path\to\success> path\to\success>perl -e "@var=system(\"success.pl\") or die \"can\'t r +un\";print \"@var \n\";" Success Ran Here0 path\to\success> # the "0" is errno from system ie, no error; # were you executing this from the same dir as holds "success.pl"? path\to\success>perl -e "@var=exec(\"success.pl\") or die \"can\'t run +\";print \"@var \n\";" and... path\to\success>perl -e "@var=exec (\"perl success.pl\") or die \"can\ +'t run\n\";print \"@var \n\";" path\to\success>Success # note the blank line before the last prompt, and the location of t +he word "success" # perldoc -f exec: The "exec" function executes a system command a +nd never returns* # If your OS (windoze?) does not have perl associated with .pl, thi +s won't work, and even if it does, IIRC, using "exec" won't assign an +ything to $var usefully, as "never returns" means everything after th +e "exec(..." won't be executed. In effect, the "exec(..." is like "ex +it;" path\to\success>perl success.pl # ie, this file Success Ran Here path\to\success> =cut open(FH, "success.pl"); @var=<FH>; close(FH); print $var;

    and if I guess *nix (as I do from the "-1" in OP's example 2):

    ww@GIG:~/pl_test$ perl -e '@var=`success.pl`;print @var;\n;' wheelerw@GIG:~/pl_test$ # nada (addressed in a prior reply) ww@GIG:~/pl_test$ perl -e '@var=system("success.pl") or die "cant run" +; print "@var \n";' -1 ww@GIG:~/pl_test$ # system error; see reply above ww@GIG:~/pl_test$ perl -e '@var=`success.pl`;print "@var\n";' ww@GIG:~/pl_test$ # note blank line between prompts ww@GIG:~/pl_test$ perl success.pl Success Ran Here ww@GIG:~/pl_test$ # newline added in 'print $var . "\n";' in *nix script =cut

    Oh yes, this summary is quite late. Thank the alarm that sent us running to a "odor of gas in a structure" call... :-)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://816345]
Approved by jettero
Front-paged by moritz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2024-04-23 11:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found