All other postings assume that the old script uses the CGI module, which has some debugging features. But there also is a generic way to fake CGI context from a shell, that works for all CGIs, written in any language. The trick is to know how CGI works, this is documented in RFC 3875.

Short summary: CGI programs are invoked with STDIN connected to a file or pipe delivering POSTed content, STDOUT connected to a file or pipe collecting output for the browser, STDERR connected to a file or pipe for logging. This is nearly the same setup you would expect from any unix command line utility. The big difference are arguments, they are passed via the environment, not as program parameters.

For a GET or HEAD request, you can ignore STDIN. If you are paranoid, redirect from /dev/null. For a POST request, you need to write the POSTed data into STDIN of the CGI program in the same format that the browser would send it to the webserver. You also have to set the environment variable "CONTENT_LENGTH" to the number of bytes in the POSTed data.

In any case, you should set the enviroment variable "GATEWAY_INTERFACE" to "CGI/1.1", as several CGIs use this to tell the difference between running in CGI mode (variable set) and running from command line for debugging (variable not set). The request method ("GET" / "HEAD" / "POST") is stored in "REQUEST_METHOD". CGI parameters that would be encoded in the URL have to be stored in the environment variable "QUERY_STRING", excluding the "?". Extra path elements in the URL, following the script URL, have to be placed in the environment variable "PATH_INFO".

Some rare CGIs need to know more, e.g. the host name from the URL ("HTTP_HOST"), the document root directory ("DOCUMENT_ROOT").

To fake a GET request for http://www.example.com/cgi-bin/some.cgi/extra/path/elements?name1=value1&name2=value2, minimally do this:

/usr/bin/env GATEWAY_INTERFACE='CGI/1.1' REQUEST_METHOD='GET' PATH_INF +O='/extra/path/elements' QUERY_STRING='name1=value1&name2=value2' /sr +v/www/cgi-bin/some.cgi

Note that you need to quote the ampersand (&), as it has a special meaning for most shells. To avoid shell traps, simply put every value in single quotes. Also note that all data from the URL stays URL-encoded (i.e. with %), decoding the values is done by the CGI.

Of course, you can put that in a shell script, that makes it easier to call the CGI program:

#!/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

You could also use a Perl script instead of bash, e.g. to set the encoded QUERY_STRING environment variable from unencoded command line arguments instead of hard-coding it:

#!/usr/bin/perl # called as wrapper.pl name1 arg1 name2 arg2 ... use strict; use warnings; sub encode { my $value=shift; $value=~s/([^A-Za-z0-9._-])/sprintf('%%%02X',ord $1)/ge; return $value; } $ENV{'GATEWAY_INTERFACE'}='CGI/1.1'; $ENV{'REQUEST_METHOD'}='GET'; $ENV{'PATH_INFO'}='/extra/path/elements'; my @pairs; while (@ARGV) { my $name=encode(shift @ARGV); my $value=encode(shift @ARGV); push @pairs,"$name=$value"; } $ENV{'QUERY_STRING'}=join('&',@pairs); exec('/srv/www/cgi-bin/some.cgi') or die "exec failed: $!";

I'm sure there is a way to do that in bash, too. But this is perlmonks, not bashmonks. ;-)

Alexander

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

In reply to Re: Running a CGI script from a command line? by afoken
in thread Running a CGI script from a command line? by shanen

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.