How to list Perl CGI environment variables

Perl CGI environment variables: How can I print all of the Perl CGI environment variables? I'd like to see what CGI environment variables are available, and what their values are.

Somewhere in my history of working with Perl and CGI programs, I decided I needed a program that would simply print all of the CGI environment variables that my Perl programs were aware of. I can't remember if it was curiosity or what, but I decided that I needed a CGI program that did nothing else but print the environment variables it knew of.

It's a few years later now, and I find that this program is still with me wherever I go. Sometimes I use it to look at CGI variables, other times I just use it to help debug an HTTP server, and other times I look at it as a reminder of how to work with associative arrays (also called hashes in the latest Perl lingo).

Regardless of the use, this little program - printenv.cgi - is a decent little program that demonstrates a few Perl capabilities you may not have seen elsewhere.

How to list Perl CGI environment variables

The best way to learn about this program is to look at the source code and the output it produces. Therefore, with no further ado, Listing 1 contains the entire source code for this little CGI program:

#!/usr/local/bin/perl

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

foreach $key (sort keys(%ENV)) {
  print "$key = $ENV{$key}<p>";
}
print "</pre>\n";

Listing 1 (above): The Perl source code for the printenv.cgi program.

So much for the source code. We'll come back and discuss it in a few minutes.

Before discussing the source code, next take a look at Listing 2. This listing shows the output that this CGI program generated when it was run from an Apache web server. Seeing the output generated by the program will help you understand how the program functions.

 DOCUMENT_ROOT = /usr/local/etc/apache/htdocs
 GATEWAY_INTERFACE = CGI/1.1
 HTTP_ACCEPT = image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
 HTTP_ACCEPT_CHARSET = iso-8859-1,*,utf-8
 HTTP_ACCEPT_LANGUAGE = en
 HTTP_CONNECTION = Keep-Alive
 HTTP_HOST = 200.210.220.1:8080
 HTTP_USER_AGENT = Mozilla/4.01 [en] (Win95; I)
 PATH = /usr/local/bin:/bin:/etc:/usr/bin
 QUERY_STRING = 
 REMOTE_ADDR = 200.210.220.3
 REMOTE_HOST = 200.210.220.3
 REMOTE_PORT = 1029
 REQUEST_METHOD = GET
 REQUEST_URI = /cgi-bin/utils/printenv.cgi
 SCRIPT_FILENAME = /usr/local/lib/apache/cgi-bin/utils/printenv.cgi
 SCRIPT_NAME = /cgi-bin/utils/printenv.cgi
 SERVER_ADMIN = adminguy@acme.com
 SERVER_NAME = coyote.acme.com
 SERVER_PORT = 8080
 SERVER_PROTOCOL = HTTP/1.0
 SERVER_SOFTWARE = Apache/1.2.5
 TZ = :US/Eastern

Listing 2 (above): Output from the printenv.cgi program, run from an Apache web server.

As you can see from Listing 2, all this program does is print out (a) the name, and (b) the value, of the environment variables that the CGI program is aware of.

Having seen these two listings, let's dig into the source code a bit to see what's going on.

The first three lines ...

The first three lines of code leading up to the foreach statement are pretty simple to figure out:

#!/usr/local/bin/perl

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

The first line tells the Unix server to use the Perl interpreter to interpret the contents of this file when it is executed. The second line prints a "content-type" statement that the Apache server and remote browser will need. This line tells them what's about to be printed. In this case, I've told them that I'm about to print some HTML code.

In the third line of the code, I print a "<pre>" HTML tag. This tag tells the remote browser that everything that follows it (until it sees a </pre> tag) should be interpreted as a typewriter font. In my opinion this makes the output of this program easier to read. It's not required, but I think the default proportional font is more difficult to read in this case.

The foreach loop and associative arrays

The next three lines of code are a bit more interesting, and look like this:

foreach $key (sort keys(%ENV)) {
  print "$key = $ENV{$key}<p>";
}

If I had to describe this code to somebody over the telephone, I'd describe it something like this: "Create a list of all the keys in the associative array %ENV. Next, sort this list of keys, and for each key in the list, print (a) the name of the key and (b) the value of the corresponding $ENV element. For appearance sake, put an HTML paragraph tag at the end of the print statement so each print statement appears as a separate line in the user's browser."

If you haven't used associative arrays in Perl before, that might have been a little confusing. If it was, just look at the output in Listing 2 again, and then look at the print statement. As you can see from the print statement and the output, each time through the loop the variable $key contains the name of an environment variable. For example, the first time through the loop $key contains the name DOCUMENT_ROOT. Then, the variable referred to as $ENV{$key} just prints the corresponding value of DOCUMENT_ROOT.

To explain it a step farther, in this example, $ENV{$key} is the same as $ENV{"DOCUMENT_ROOT"}. Since %ENV is an associative array (that's what the % symbol tells us), it's indexed by strings, not by numbers. So, instead of saying things like $ENV(1) you'd write for a regular array, we can write more convenient things like $ENV{"DOCUMENT_ROOT"}, or $ENV{"GATEWAY_INTERFACE"}.

Perl CGI environment variables - Where did %ENV come from?

The only remaining mystery is where the %ENV associative array came from. We didn't define it anywhere, so I'm thinking it must be some type of special array, right?

Right.

%ENV is a special variable in Perl that contains the environment variables of your current environment. It doesn't have any special meaning for CGI scripts - you can run this same program from your Unix command line and get totally different results. (Of course before you do that you might want to get rid of the HTML tags and add a carriage return at the end of the print statement.)

Perl CGI environment variables - Summary

The simple Perl program described in this article uses the special variable %ENV to print out the environment variables in effect when this program is executed. The program prints the name of each environment variable, as well as the value of each variable. This can be very helpful when you're debugging CGI programs.

The foreach loop demonstrated in this program can be used any time you want to see the values of any associative array, not just %ENV. I often look at this code as a reminder of how to retrieve and sort the keys of an associative array.

Reader Follow-Up Comments:

From: Dave Cross (and another anonymous reader)

You should be encouraging the use of CGI.pm for CGI scripts.

Reply:

No argument there. We definitely encourage the use of the CGI.pm module for intensive Perl/CGI scripts. As a small example, we didn't think it was warranted here, because it carries a fairly substantial overhead to load. In most of our CGI scripts, though, we do use CGI.pm, and we'll write more than a few articles about it as time goes on. As usual with Perl, There's More Than One Way To Do It.