CGI: Execute a perl script inside another perl script

Discussion in 'Perl Misc' started by xdarcos, Jan 12, 2005.

  1. xdarcos

    xdarcos Guest


    I am using perl scripts as CGI. What I want to do is to call another
    perl script where I only set environment variables (

    If I set these variables in my initial perl script, it works well (I
    get my HTML page) but if I call the other perl script, I get:

    [12/Jan/2005:10:43:22] failure ( 632): for host trying
    to POST /surcouf.cgi, cgi_scan_headers reports: HTTP4044: the CGI
    program C:\Perl\bin\perl.exe did not produce a valid header (program
    terminated without a valid CGI header. Check for core dump or other
    abnormal termination).

    Here is my perl script:



    //Then an exe is executed (in which the content-type is set) and the
    HTML page is well displayed.
    $matchAdmin = "Routage%3DADMIN";
    $matchConso = "Routage%3DCONSO";
    if ($ENV{QUERY_STRING} =~ /$matchAdmin/)
    $cmd = 'admin.exe'; exec($cmd);
    elsif ($ENV{QUERY_STRING} =~ /$matchConso/)
    $cmd = 'conso.exe'; exec($cmd);
    $cmd = 'contrat.exe'; exec($cmd);

    I tried also to use: system(''). There are no errors but the
    variables are not set. Is there an equivalent of EXPORT command of Unix

    Thanks for your help
    Note:I am using SunOne Web Server 6.1 and I am under Windows 2000
    xdarcos, Jan 12, 2005
    1. Advertisements

  2. xdarcos

    Paul Lalli Guest

    You need to read up on what exec actually does
    perldoc -f exec

    this launches an entirely seperate process. Any environment variables
    set in that process are set only for that process.

    If your seperate file is only modifying globals (which %ENV is), you can
    just use the do 'file' syntax.

    perldoc -f do

    Paul Lalli
    Paul Lalli, Jan 12, 2005
    1. Advertisements

  3. Why don't you have:

    use strict;
    use warnings;
    Have you read the docs for the exec() function?

    perldoc -f exec
    Odd way to set content-type in a Perl program.
    Have you read the docs for the system() function?

    perldoc -f system

    Don't just try, read the docs, too.

    Anyway, neither exec() nor system() is an appropriate way to include a
    Perl program in another Perl program. I suppose that you should use 'do'

    do '';

    See "perldoc -f do".
    Gunnar Hjalmarsson, Jan 12, 2005
  4. Your Question is Asked Frequently, please see "perldoc -q environment":

    I {changed directory, modified my environment} in a perl script. How come
    the change disappeared when I exited the script? How do I get my changes to
    be visible?

    Jürgen Exner, Jan 12, 2005
  5. And nothing beyond this line executes, since completely
    replaces the currently running program. perldoc -f exec.
    Of course not. system spawns a child process. What the child
    process does with its environment variables cannot affect the
    Er, you don't understand environment variables. Children cannot affect
    the environment of their parents. This is universally true in Unix, and
    export can't--and doesn't--change that.
    Don't know much about environment variables in Windows, but your approach
    seems to be fundamentally flawed.

    Christopher Mattern

    "Which one you figure tracked us?"
    "The ugly one, sir."
    "...Could you be more specific?"
    Chris Mattern, Jan 12, 2005
  6. xdarcos

    xdarcos Guest

    Thanks all for your answers but it doesn't work yet :-(.
    So OK, 'exec' is not the good solution, neither 'system'.
    I didn't know the 'do' function, I tried it but without success: in my
    exe, the environnement variables I have set in '' are still

    Regarding "perldoc -q environment" Jürgen, this is dedicated to Unix
    and I am using Windows

    Note that my exe is developed in C++, not in perl. The perl script is
    here to call the right exe depending on the query string.
    Any new help will be welcome.
    xdarcos, Jan 12, 2005
  7. Please always produce a _minimal_ but _complete_ test case.

    I just did this on my windows box here and was unable to reproduce the
    do '';
    system 'cmd';

    When I run the child cmd.exe could see the environment variable set

    Rather than expecting each person who tries to help to produce a minimal
    but complete test case to attempt to reproduce the symptoms is is much
    more efficient (and polite) for the person asking the question to do so.

    Often the act of doing so will find the problem.

    Have you read the posting guidelines that are posted here frequenting?
    They contain a lot of valuable advice that will help you to get answers
    and also help you to avoid accidently giving the appearance of being
    What it says applies largely to Windows too. I believe there is in
    Windows a way to alter the environment variables of another process -
    but that's low-level OS-specific stuff that you'd need to discuss in an
    OS specific group.
    Brian McCauley, Jan 12, 2005
  8. Actually, this particular behaviour (modifications of the environment of a
    child process will never be back-propped to the parent process) applies to
    Windows, too.

    Jürgen Exner, Jan 13, 2005
  9. xdarcos

    xdarcos Guest

    Hello all,

    I found your responses very strong and the idea of you might think that
    I am "lazy/arrogant/selfish" make me feel uncomfortable because this is
    not me. So the word "accidently" was well chosen because this was not
    at all my purpose.
    What I didn't mention is that I was a real perl beginner. My first
    script was working well but all the environment variables were in it.
    So I decided to move them to another one. You mentioned to have a look
    to "perldoc -f do" OK but if you don't know the "do" command, it is not
    so easy. I can also maybe explain that because I am not fluent in
    English, my question could have been felt too direct. I would like to
    apologize if it is what you felt.

    To come back to my problem:
    Brian, the short example you gave me works well also for me.
    But when I try to use it with my web server (SunOne Web Server), it is
    not working anymore:
    do '';

    print "Content-type:text/html\n\n";
    print "<html><head><title>HTTP Environment</title></head> <body>";
    print "FOO=".$ENV{FOO};
    print "</body></html>";

    Here is the output I get in my HTML browser:

    To be more complete in my investigation, I tried also with Apache and
    here is what I get:
    This works !!
    So it seems this is a configuration problem of SunOne i.e nothing to do
    with Perl.

    Thanks for time and sorry for the inconvenience.
    Have a good day.
    xdarcos, Jan 13, 2005
  10. As you say this is not related to Perl. The CGI standard does not define
    the setting of the current working directory when a CGI process is
    spawned. In the case of Apache it (almost?) always sets the CWD to the
    directory containing the script. I'm guessing that SunOne does not do
    this. You need to use a fully qualified filename in the do().
    Brian McCauley, Jan 13, 2005
  11. xdarcos

    xad Guest

    Thanks for your response. You were right, it works with the full path
    to the script in the do().
    The only concern is that I also wanted to put all environment variables
    in one script in order to give users the ability to modify it by
    setting their own configurations files, and in another side keeping a
    generic root script not to be modified. So now they will also need to
    modify the root script.
    Anyway I thought that SunOne Web Server was based on Apache. Isn't it
    right ?

    xad, Jan 13, 2005
  12. I think it is.
    "do" does not use the working directory, it searches @INC if the path is

    perldoc -f do
    Suppose you mean the full path. That always works, of course, but you
    can also do:

    use lib '.';
    do '';
    Gunnar Hjalmarsson, Jan 13, 2005
  13. It should be noted that a simple check for success would have saved you
    some trouble:

    do '' or die "Couldn't execute $!";
    Not if you do:

    use lib '.';
    do '';

    See my reply to Brian.
    Gunnar Hjalmarsson, Jan 13, 2005
  14. I always seem to forget that. For some inexplicable reason I always
    imagine that the @INC search is in require() not in the lower level do().
    Brian McCauley, Jan 13, 2005
  15. And why do you think that if called with an absolute path the child process
    would be able to overwrite environment variables in the parent process?

    Jürgen Exner, Jan 16, 2005
  16. Why would the hon Usenaut need to "try" it? - aren't you sure it's
    going to work? Where's your explanation of what you suppose the
    questioner was doing wrong? Where's your explanation of how you
    imagine the called process is going to be able to set environment
    variables in the calling process?
    TOFU posters rarely do. Statistically, in my experience, their
    answers rarely address the substantive issues in the material that
    they are so comprehensively quoting - but rarely, it seems, bothered
    to read.

    [ fullquote snipped ]

    That's the point, just in case you still didn't get it.
    Alan J. Flavell, Jan 16, 2005
  17. xdarcos

    Wes Groleau Guest

    "require" works OK for this. Or at least I think it
    worked. It's been three or four years since I did it.

    Wes Groleau

    Answer not a fool according to his folly,
    lest thou also be like unto him.
    Answer a fool according to his folly,
    lest he be wise according to his own conceit.
    -- Solomon

    Are you saying there's no good way to answer a fool?
    -- Groleau
    Wes Groleau, Jan 16, 2005
  18. xdarcos

    xad Guest

    Actually it does not work yet.
    use lib '.';
    do '';

    print "Content-type:text/html\n\n";

    print @INC;
    print "|FOO=".$ENV{'FOO'};
    With that code, I can see that @INC is well updated. Indeed, the
    following output is printed out in my browser
    but the script is not executed.

    If I replace
    use lib '.';
    use lib 'D:/cc_views/v3_4/Dev/bin'; (that corresponds to the location
    of the 2 scripts),
    @INC is updated with the new location:
    and the script is well executed (FOO has been set to BAR)

    It seems that SunOne Web Server does not interpret the '.' location ?

    PS: "require" command has the same behavior
    xad, Jan 18, 2005
  19. Maybe it doesn't acknowledge relative paths in @INC. Then, to prevent
    that the users need to edit the main script, you can try to manipulate
    @INC like this instead:

    use lib $0 =~ /(.+)[\\\/]/;

    (Or you can use the FindBin module, even if it isn't mod_perl or taint
    Gunnar Hjalmarsson, Jan 18, 2005
  20. xdarcos

    xad Guest

    Thanks a lot Gunnar, both solutions work well.
    Have a good day.

    xad, Jan 18, 2005
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.