Environment variables

Environment variables are variables defined within the operating system or shell at any given time. They typically hold information that may be useful to commands or programs running within the operating environment.

You may use any UNIX environment variable within a Perl script. To use an environment variable, use a string of characters like $ENV{'variable'} where you replace the word variable with the name of the environment variable of interest. For example, to use the REMOTE_HOST environment variable within an Perl script, use the string $ENV{'REMOTE_HOST'}. The following fragment prints the value of the Present Working Directory environment variable, PWD:

#!/usr/local/bin/perl
print "Content-type:text/html\n\n";
print <<EOM;
The current working directory is $ENV{'PWD'}
EOM
The following environment variables are established by the Web server, the Perl interpreter, and/or CGIWrap and may be used in Perl scripts, followed by some sample values:
     SERVER_SOFTWARE="Apache/1.1.3"
     GATEWAY_INTERFACE="CGI/1.1"
     DOCUMENT_ROOT="/home/WWW"
     REMOTE_ADDR="198.110.193.111"
     SERVER_PROTOCOL="HTTP/1.0"
     REQUEST_METHOD="POST"
     REMOTE_HOST="ogimaa"
     HTTP_REFERER="http://euclid/~randy/Classes/CS495.Winter98/sample_form.html"
     QUERY_STRING=""
     HTTP_USER_AGENT="Mozilla/4.03 [en] (X11; I; Linux 2.0.30 i686)"
     PATH="/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/usr/bin/mh:/usr/X11R6/bin:/usr/bin/mh:/home/randy/bin:/.:/sbin:/usr/sbin"
     HTTP_CONNECTION="Keep-Alive"
     HTTP_ACCEPT="image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"
     HTTP_ACCEPT_LANGUAGE="en"
     SCRIPT_NAME="/~randy/Classes/CS495.Winter98/test.cgi"
     SCRIPT_FILENAME="/home/randy/pub/Classes/CS495.Winter98/test.cgi"
     SERVER_NAME="euclid.acs.nmu.edu"
     HTTP_ACCEPT_CHARSET="iso-8859-1,*,utf-8"
     SERVER_PORT="80"
     CONTENT_LENGTH="48"
     CONTENT_TYPE="application/x-www-form-urlencoded"
     HTTP_HOST="euclid"
    SERVER_ADMIN="root@localhost"
If you define an environment variable within your (parent) Perl script, (child) scripts started by your (parent) script may use it. If you start child scripts that change the values of environment variables defined in the parent script, however, the parent script will not see the changes: the child script cannot send information back to the parent via environment variables. Environment variable names are case sensitive.
 

 

Building and using counters

Counters are widely used on the World Wide Web to see how many people examine HTML documents. A counter is usually implemented as an ordinary file that is used to hold a single value--the number of accesses to a particular document. To build a counter, you must first create a count file. This file contains only the (ASCII) number at which you would like the counter to start. You can build a count file using any editor on your system. Assuming this file is called counter.file, a Perl script to use it would look like
#!/usr/local/bin/perl
#
open(COUNTER, "+< /home/smith/counter.file");  
             # open the counter file with read and write access.
$COUNT= <COUNTER>;           #read the current value. 
$COUNT++;                    #increment it by one.
seek(COUNTER, 0 , 0);        #rewind the file.
print COUNTER $COUNT;        #write the new value to the file.
close COUNTER;
The line $COUNT++; adds one to the value of the variable $COUNT.

To include the number from the count file in a document, use the print command as before. For example, you might build a Perl script like the following:

#!/usr/local/bin/perl
print "Content-type:text/html\n\n";
#
#First, increment the counter:
#
open(COUNTER, "+< /home/smith/counter.file");
             # open the counter file with read and write access.
$COUNT= <COUNTER>;           #read the current value.
$COUNT++;                    #increment it by one.
seek(COUNTER, 0 , 0);        #rewind the file.
print COUNTER $COUNT;        #write the new value to the file.
close COUNTER;
#
#Then use the counter in the returned HMTL.
#
print <<END_OF_PAGE;
<html>
<title>My first return page</title>
<h1>Thank you for selecting this document.</h1>
You are visitor number $COUNT
</html>
END_OF_PAGE
This script reads the counter file into a variable called COUNT, increments the counter variable by one, stores the new value in the counter file, and then returns an HTML document that uses the counter variable.

Sharing files among scripts

If multiple users run this script at the same time, strange things may occur. It is possible, for example, that the two running scripts would read the current count at the same time, increment it by one at the same time, and store the new value in the file, reflecting access by just one user instead of both. The chances of experiencing difficulties due to such concurrent access vary according to the type and frequency of access. In many cases, the frequency of document access is small, so the chances of simultaneous access are small enough to ignore.

However, Perl does include facilities for synchronizing file accesses. Among others, the flock function allows users to lock a file for private use. You could use the line

flock (COUNTER, 2);
to lock the file immediately after opening the file and the line
flock (COUNTER, 8);
to unlock the file immediately before closing it.

This problem applies to other Perl building blocks and to scripts that simultaneously write to, or simultaneously write to and read from the same file, written in any language . In general, the problem can be controlled by giving any writing script private access. That is, if a script is writing, no other writers or readers will be given access until that script is finished. The Perl flock function grants such privacy.

On the other hand, any solution will have drawbacks. For example, it may be inconvenient to lock the file for a long period of time, in which case other approaches may be needed.   The values you can pass to flock are

You can use multiple versions by adding them together.  For instance, a shared nonblocking lock is 9.


Mailing information to users from a script

You can use a Perl script to e-mail information to you whenever users activate the "Submit form" button on your form. The Perl commands to do this take the following form:
open (MAIL, "| /usr/lib/sendmail -oi -n -t" );
print MAIL <<MAIL_MESSAGE;
To:username\@www.cc.ukans.edu
From:username\@www.cc.ukans.edu

You have just sent info about vegetarianism to another interested person.
MAIL_MESSAGE

close MAIL;
The information in the To: and From: clauses can be any e-mail address. Reply-to: and Return: clauses can be appended to identify to whom any return message should be sent. These are not always the same as the From: address. You can also include a Subject: clause.

After these lines, you may add any text you want, including field names embedded within $in{...} strings. You might construct the following fragment to mail information to the requestor:

require ("/usr/local/lib/perl5/cgi-lib.pl");
&ReadParse;

open (MAIL, "| /usr/lib/sendmail -oi -n -t" );
print MAIL <<MESSAGE_TO_USER;
To:$in{'address'}
From:smith\@www.cc.ukans.edu

Dear $in{'name'}:
Here are some books that talk about vegetarianism:

     Diet for a New America
     How to Avoid Beef

MESSAGE_TO_USER

close MAIL;
In this example, "name" and "address" are names of fields specified in the example form, and they would be replaced by the user's name and e-mail address in the actual e-mail message sent to her. In this example, both the mail header information and the enclosed mail message contain references to fieldnames.