in reply to Re: Running a CGI script from a command line?
in thread Running a CGI script from a command line?

Okay, finally some progress to report, though I mostly feel increasingly ignorant in spite of the expert guidance. I can make it work by inserting the "QUERY_STRING" (without the leading "&" into the subroutine that appears below... In other words, the problem seems to be that there is nothing I can figure out that will get the parameter string into the QUERY_STRING part of the environment.

This mostly captures my past experiences with PERL... Enlightenment eludes me.

In particular, I cannot understand why the explicit command line assignment to QUERY_STRING fails. That is both the assignment in a PERL command line and the assignment with the shell set command. "These are not the ENV variables you are searching for..."

Right now I feel like rewriting the entire thing in Python. Is that sacrilegious, or just practical?

sub html_parse { local($line, $length, $offset, @pairs); # Just use a GET and the one line? $line = $ENV{"QUERY_STRING"};
Freedom = (Meaningful - Coerced) Choice ≠ (Beer | Speech)

Replies are listed 'Best First'.
Re^3: Running a CGI script from a command line?
by hippo (Archbishop) on Jun 17, 2015 at 09:03 UTC

    OK, time for a SSCCE. See if you can follow this simple illustration. If not, please reply and explain explicitly which bit you cannot reproduce or do not understand.

    bash-$ cat my.cgi #!/usr/bin/perl use strict; use warnings; use CGI::Lite (); my $cgi = CGI::Lite->new; $cgi->parse_form_data; print "Content-type: text/plain\n\n"; $cgi->print_form_data; bash-$ export REQUEST_METHOD=GET bash-$ export QUERY_STRING='foo=bar&baz=quux' bash-$ ./my.cgi Content-type: text/plain foo = bar baz = quux

    In this example I have shown you the trivial CGI code, demonstrated how to set the two key environment variables from within the shell (any Bourne-like shell will use this syntax) and then run the script from within the same shell process to show that it has processed the supplied query string.

    Note, I've used CGI::Lite here for brevity but any of the CGI modules from CPAN should work in a similar fashion as explained by afoken above.

    Update: Amended $PS1 for even more clarity, just in case.

Re^3: Running a CGI script from a command line?
by Anonymous Monk on Jun 17, 2015 at 09:26 UTC

      The sin of my code fragment was that it violated the commandment of self-containment. ;-) That piece was actually from one of the oldest parts of an ancient and heavily modified source.

      Unfortunately, I can't use the bash example right now, since I'm on a Windows box during these hours. Even without the bash shell on this machine, I studied the approach it describes for a while. No light bulb yet, though I feel as though I'm nearing enlightenment on the ENV variables...

      I was actually testing my kludgy fix on a Linux box last night, and will try to understand that bash approach more carefully when I'm on that machine. Overall, I am extremely grateful for the kindness that my rather profound ignorance has received here.

      However, from considering the last comment (the one after the bash shell idea) I realize that I feel like the best conclusion is to abandon CGI completely and just do it a more direct way. I have (once again) allowed myself to be misled by legacy code, some of which is at least 20 years old.

      Perhaps the main reason I stopped being a professional programmer was that my fate appeared to be maintenance programming. I tend to worship the old code and continue fixing it long after it should get the page-one rewrite. (However, I wasn't really joking about switching to Python, since it's my most recent language, and one that I'm studying a bit more systematically. My studies of PERL were never systematic or intense, but there are some aspects of PERL that I found quite intriguing when that old code was bequeathed to me...)

      As things stand right now, I am able to use the original PERL with only minor tweaks. I have already assembled a group of reporting commands that cover my primary uses. Clumsy, but adequate for now.

      Freedom = (Meaningful - Coerced) Choice ≠ (Beer | Speech)
        I can't use the bash example right now, since I'm on a Windows box

        That example works as well on windows, but you have to adapt it to the syntax of Windows' batch files:

        bash:

        #!/bin/bash export GATEWAY_INTERFACE='CGI/1.1' export REQUEST_METHOD='GET' export PATH_INFO='/extra/path/elements' export QUERY_STRING='name1=value1&name2=value2' exec /srv/www/cgi-bin/some.cgi

        batch:

        @echo off set GATEWAY_INTERFACE="CGI/1.1" set REQUEST_METHOD="GET" set PATH_INFO="/extra/path/elements" set QUERY_STRING="name1=value1&name2=value2" perl C:\srv\www\cgi-bin\some.cgi

        Note that this assumes the CGI is a perl script. For a CGI *.exe file, the batch file should look like this:

        @echo off set GATEWAY_INTERFACE="CGI/1.1" set REQUEST_METHOD="GET" set PATH_INFO="/extra/path/elements" set QUERY_STRING="name1=value1&name2=value2" C:\srv\www\cgi-bin\some-cgi.exe

        Also note that there is a minor difference: The bash file replaces itself with the CGI after modifying the environment (that's what exec does), the batch file just runs the CGI as a subprocess. That's simply because Windows has neither exec nor fork. (Windows perl versions implement fork and exec as emulations, but they are far from the original.)


        If the CGI is a perl script, you can use the perl wapper script as well, even on Windows, with a little modification: Replace the final line exec('/srv/www/cgi-bin/some.cgi') or die "exec failed: $!"; with do 'c:\srv\www\cgi-bin\some.cgi';. This will load the CGI script into the wrapper script, running it in the same process as the wrapper. See do.

        Note that the wrapper script and the CGI script share the same namespace here, so the names of routines and variables may collide (sub encode and my @pairs in my example). If that is a problem, rename the variables and/or routines or consider moving the setup into a module.


        One final thing: "Perl" is the name of the language. "perl" is the name of the implementation. "PERL" is just nonsense.

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

        Okay, thanks again, and I think this is just to put closure on the topic (though I was still hoping for more enlightenment if there were any new comments). In summary, I was able to solve my immediate problem, and even succeeded in running the PERL in question on an ancient Linux box where another part of the system still lives (like a zombie). Running it there actually creates a new wrinkle that eliminates some of the later steps (which had involved running the code on current versions of Linux, Windows 7, and the Mac OS). Now it seems to work anywhere I want it, and the results are as good as ever (for small values of 'good').

        On the down side, I still don't understand how it worked before, but if I tackle that part of the problem again, I'm only going to do it with a webserver under me so I can see what is really happening there. However, if it ever gets back to a webserver, I'm pretty sure it needs a page-one rewrite and this PERL is back on page 17 or later...

        Freedom = (Meaningful - Coerced) Choice ≠ (Beer | Speech)