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

Hi
I'm trying to pass arguemnts to a child.pl script via a parent script. My child script is as follows -
#!/usr/bin/perl -w use strict; $|++; use CGI; my $cgi = CGI->new; my $number = $cgi->param('number'); print "param: ".$number."\n"; my $n; print "Command line reporter\n";print "Called with ",$#ARGV+1," parameters which ", @ARGV == 1 ? "was" : "were" ,"\n";print (++$n,": $_\n") foreach (@ARGV) ; for(my $i=0;$i<$number;$i++) { print("*\n"); sleep 1; }
when I run this script from the command line, as follows -
 perl child.pl number=4
I get -
param: 4 Command line reporter Called with 1 parameters which was 1: number=4 * * * *

But when I call it from the parent script as follows -
exec '/usr/bin/perl', '-T', 'child.pl', 'number=10' or die "Cannot execute : $!";

I get -
Use of uninitialized value in concatenation (.) or string at child.pl +line 10. param: Command line reporter Called with 1 parameters which was 1: number=10 Use of uninitialized value in numeric lt (<) at child.pl line 17.

ARGV works, but not param, what am I doing wrong?
Thanks in advance.

Replies are listed 'Best First'.
Re: Passing Args via Exec
by superfrink (Curate) on Aug 28, 2004 at 01:54 UTC
    Works for me with v5.8.0 (Slackware 9.1 install) What version of CGI.pm are you using? print CGI->version; prints 2.81 for me.

    Update: I didn't read thing clear enough but I think it still works.
    [frink@truth ~/code/perl]$perl 386513.pl number=4 param: 4 Command line reporter Called with 1 parameters which was 1: number=4 * * * * [frink@truth ~/code/perl]$perl 386513.pl-exec param: 4 Command line reporter Called with 1 parameters which was 1: number=4 * * * * [frink@truth ~/code/perl]$cat 386513.pl-exec #!/usr/bin/perl exec '/usr/bin/perl', '-T', '386513.pl', 'number=4' or die "Cannot execute : $!"; [frink@truth ~/code/perl]$perl -v This is perl, v5.8.0 built for i486-linux
      CGI Version 3.05
      I tried -
      #!/usr/bin/perl exec '/usr/bin/perl', '-T', '386513.pl', 'number=4' or die "Cannot execute : $!";
      and it worked when I called the above from the command line. My calling script must be the problem so, and I run it using my browser. Here it is, can you see the problem? The code is a simple rework of - http://www.stonehenge.com/merlyn/LinuxMag/col39.html
      #!/usr/bin/perl -w use strict; $|++; $ENV{PATH} = "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local +/sbin"; use CGI qw(:all delete_all escapeHTML); sub show_form { print header, start_html("Traceroute"), h1("Traceroute"); print start_form; print submit('traceroute to this host:'), " ", textfield('host'); print end_form, end_html; } sub get_cache_handle { require Cache::FileCache; Cache::FileCache->new ({ namespace => 'tracerouter', username => 'nobody', default_expires_in => '30 minutes', auto_purge_interval => '4 hours', }); } sub get_session_id { require Digest::MD5; Digest::MD5::md5_hex(Digest::MD5::md5_hex(time().{}.rand().$$)); } if (my $session = param('session')) { # returning to pick up session +data my $cache = get_cache_handle(); my $data = $cache->get($session); unless ($data and ref $data eq "ARRAY") { # something is wrong show_form(); exit 0; } print header(), start_html(-title => "Traceroute Results", ($data->[0] ? () : (-head => ["<meta http-equiv=refresh content=5>"]))); print h1("Traceroute Results"); print pre(escapeHTML($data->[1])); print p(i("... continuing ...")) unless $data->[0]; print end_html; } elsif (my $host = param('host')) { # returning to select host if ($host =~ /^([a-zA-Z0-9.\-]{1,100})\z/) { # create a session $host = $1; # untainted now my $session = get_session_id(); my $cache = get_cache_handle(); $cache->set($session, [0, ""]); # no data yet if (my $pid = fork) { # parent does delete_all(); # clear parameters param('session', $session); print redirect(self_url()); } elsif (defined $pid) { # child does close STDOUT; # so parent can go on unless (open F, "-|") { open STDERR, ">&=1"; exec '/usr/bin/perl', '-T', 'child.pl', 'number=4' or die "Cannot execute : $!"; } my $buf = ""; while (<F>) { $buf .= $_; $cache->set($session, [0, $buf]); } $cache->set($session, [1, $buf]); exit 0; } else { die "Cannot fork: $!"; } } else { show_form(); } } else { # display form show_form(); } exit 0;
        OK, I'm now trying the following parent called new3.cgi -
        #!/usr/bin/perl -w use strict; $|++; $ENV{PATH} = "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/ +sbin"; use CGI qw(:all delete_all escapeHTML); print header(), start_html(-title => "Traceroute Results"); print h1("Traceroute Results"); #open STDERR, ">&=1"; exec '/usr/bin/perl', '-T', 'child.pl', 'number=4' or die "Cannot exec +ute : $!"; print end_html;

        I call this on the command line with perl new3.cgi and get -
        Content-Type: text/html; charset=ISO-8859-1 <?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-U +S"><head><title>Traceroute Results</title> </head><body><h1>Traceroute Results</h1>param: 4 Command line reporter Called with 1 parameters which was 1: number=4 * *
        I then call this with my browser and get -
        Traceroute Results param: Command line reporter Called with 1 parameters which was 1: num +ber=4 * *

        but if I uncomment the line - open STDERR, ">&=1"; I get -
        Traceroute Results Use of uninitialized value in concatenation (.) or string at child.pl +line 10. param: Command line reporter Called with 1 parameters which +was 1: number=4 * *

        The command line call is working fine, the browser calls are not
        So I'm guessing my problem has something to do with buffering. Any suggestions?
Re: Passing Args via Exec
by El Linko (Beadle) on Aug 28, 2004 at 00:10 UTC
    This seems to be working fine for me on linux using perl 5.6.1. What version of perl are you using?
      v5.8.4
        I'm lost, what should I do? Thanks.