http://www.perlmonks.org?node_id=488647

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

Hi Monks,

I'm attempting to call a .cgi script from another one of my scripts and for some reason it is only recognising the first var I pass to it.
i.e.
`perl some_script.cgi blah=foo larh=bar`;
and some_script.cgi is only seeing the results from var blah
Anyone got any ideas?

Cheers,
Reagen

Update: I've done a bit more investigating and it appears that the script being called from the original script is using the var's from that original script.
i.e. some_script.cgi?blah=foo&larh=bar will pass the vars blah and larh onto the script that some_script.cgi calls...
make sense?
I havent been able to work out how to prevent that and specify my own when I call the script. Anyone?
Here's some code that explains more clearly than I:
script1.cgi
#!/usr/bin/perl use strict; use warnings; use CGI qw(:all); print header; my $blah = `perl ./tmp.cgi 'var1=one&var2=two'`; print "<pre>", $blah, "</pre>\n"; exit;
script2.cgi
#!/usr/bin/perl use strict; use warnings; use CGI qw(:all); my $q = new CGI; my $var1 = $q->param("var1"); my $var2 = $q->param("var2"); print $var1, "\n"; print $var2, "\n"; exit;
The only way I can get var1 and var2 to print is by calling script1.cgi?var1=one&var2=two even though I define that in script1 where I call script2.

Replies are listed 'Best First'.
Re: CGI from another script
by jeffa (Bishop) on Sep 02, 2005 at 13:50 UTC

    You have to use the magic ampersand:

    `perl some_script.cgi 'blah=foo&larh=bar'`;

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      i wrote a couple of test scripts before posting and they seemed to work fine without the ampersand...
      tmp.pl
      #!/usr/bin/perl use strict; use warnings; my $id = 1; my $auth_id = 150; my $blah = `perl ./tmp.cgi id=$id auth_id=$auth_id draw=1 raw=raw`; print $blah, "\n"; exit;
      tmp.cgi
      #!/usr/bin/perl use strict; use warnings; use CGI qw(:all); my $q = new CGI; my $id = $q->param("id"); my $auth_id = $q->param("auth_id"); my $draw = $q->param("draw"); my $raw = $q->param("raw"); print $id, "\n"; print $auth_id, "\n"; print $draw, "\n"; print $raw, "\n"; exit;
      I wonder if it is because the first one was a perl script run from the command line rather than a cgi from the browser?
      Update: I just updated my original script and the amp's arent helping either. But they do still work in the test script... hmmmm
        ... or because the quoting (or OS) is different? Compare jeffa's -- which adds single quotes (which the op lacks) around the var list as well as the ampersand.
Re: CGI from another script
by ikegami (Patriarch) on Sep 02, 2005 at 14:12 UTC

    The CGI spec specifies what you be on the command line, in the environment and on standard input. Among other things, it explicitely states "The command line is only used in the case of an ISINDEX query.", a type of request I haven't seen used since 1995.

    Update: Untested:

    my $response; { # Protect the parent script's environment. # I hope this doesn't remove %ENV's magic. local %ENV = %ENV; $ENV{SERVER_PROTOCOL} = 'HTTP/1.0'; $ENV{REQUEST_METHOD} = 'GET'; # To build URLs. $ENV{SERVER_NAME} = 'www.example.com'; $ENV{SERVER_PORT} = 80; $ENV{SCRIPT_NAME} = '/some_script.cgi'; # For /xxx.cgi/path delete $ENV{PATH_INFO}; delete $ENV{PATH_TRANSLATED}; # Unset these for POST. $ENV{QUERY_STRING} = 'blah=foo&larh=bar'; # Set these for POST. delete $ENV{CONTENT_TYPE}; delete $ENV{CONTENT_LENGTH}; $ENV{REMOTE_ADDR} = '127.0.0.1'; # Need to place data on child's STDIN for POST. # Need to place data on paramater line for ISINDEX queries. $response = `perl some_script.cgi`; }
Re: CGI from another script
by kutsu (Priest) on Sep 02, 2005 at 15:41 UTC

    that is a valid way to call a cgi script from the command line so we'd need to see "some_script.cgi" to be able to tell why it's not working.

    On another note, are you calling this second cgi script with backticks? I've never seen this as a good idea - everytime it's either needed changed into a module, called with a form, or ran using a redirect. So if you could give your reason for using backticks maybe we could find a better solution.

    "Cogito cogito ergo cogito sum - I think that I think, therefore I think that I am." Ambrose Bierce

      Hi, thanks for your reply.

      I'm not sure I follow what you mean by "everytime it's either needed changed into a module, called with a form, or ran using a redirect".

      Isnt backtick and system() both the same, or are you saying its a bad idea to use either of these fullstop?

      The reason I am using this method is because I have some scripts which i need the output from. Ideally I want to rewrite them in module format but at the moment dont have the time.

        backticks and system are not the same (seeing as you want to capture the output backticks is proably what you want) but yes using system or backticks always opens up a potential security hole anytime it's used (not to say it can't be closed).

        The main point is that a cgi script where a module is needed is confusing and harder to maintain - I just wanted to make sure you were aware of this. Though make sure the script is read-only as you are calling it with 'perl ...' and this will prevent it from being called through the webserver.

        "Cogito cogito ergo cogito sum - I think that I think, therefore I think that I am." Ambrose Bierce