============================= Building a CGI Script on Unix ============================= -IAN! idallen@idallen.ca A CGI script is a dynamically-generated web page. The content of the page is produced not from a static text file, but rather from the output of programs running on the web server when you download the page. The content of the web page changes depending on the output of the program. You can build a dynamic web page using Unix commands, without knowing any Perl or other CGI scripting language. Here's how. 1) Create a public_html directory in your HOME directory on the Course Linux Server. Make sure it has read and execute permissions for everyone. 2) Create a file named public_html/hello.txt and put some text into it. Make sure the file is readable by everyone. 3) Enter a URL in this format into your web browser: http://net2003.idallen.ca:8888/~abcd0001/ Replace abcd0001 with your Unix userid. Make sure you put all the punctuation characters in the right places. If you get a permission denied error, fix the permissions on the public_html directory. Make sure the public_html directory has both "r" *and* "x" permissions for everyone. Make sure your userid has a tilde ('~') in front of it. You should now see the name of your hello.txt file. Click on it to make the text file display in your browser. If you get a permission denied error, fix the permissions to allow others to read the file. (The file needs "other" read permissions to allow the web server to read the file and serve it to your browser.) 4) Create a cgi-bin directory inside the public_html directory. Make sure it has execute permissions for everyone. Once again enter the URL: http://net2003.idallen.ca:8888/~abcd0001/ and make sure you can see the new cgi-bin directory name as well as your hello.txt file. If you click on the cgi-bin directory in your browser you will note that the web server will not let you see files in that directory. 5) Put these next lines of text into the file public_html/cgi-bin/date.cgi. The lines must start at the left margin. No indenting! No blank line! #!/bin/sh -u # This is a CGI script. PATH=/bin:/usr/bin ; export PATH umask 022 LC_COLLATE=C ; export LC_COLLATE echo "Content-Type: text/plain" echo "" date Display and word-count the file to verify that it looks EXACTLY as above. $ wc public_html/cgi-bin/date.cgi 8 24 158 public_html/cgi-bin/date.cgi You can also checksum the file to make sure it is the same as mine: $ sum public_html/cgi-bin/date.cgi 58100 1 6) Turn on read and execute permissions (for you, group, and other) on the new date.cgi file. Remove write permissions for group and others from the file and from the cgi-bin directory in which it resides. (The web server will not run a CGI script with group or other write permissions turned on.) 7) Test the executable file at the shell prompt first: $ cd public_html/cgi-bin $ ./date.cgi Content-Type: text/plain Mon Feb 14 10:08:48 EST 2005 Verify that the first line of output is "Content-Type: text/plain". The second line must be blank. The last line should be the output of "date". Fix any errors you find. The output should be three lines and exactly 55 characters: $ ./date.cgi | wc 3 8 55 8) Call up your executable file using your web browser (Mozilla): http://net2003.idallen.ca:8888/~abcd0001/cgi-bin/date.cgi You should see the current date. Refresh or reload the page, and you will see the seconds change on each refresh as the script executes. If you have errors, go back and re-do the previous steps. 9) In your date.cgi script, you can experiment by adding any other Unix commands you know. You can change the commands at the end of the script to do anything you want. You can also use "wget" or "lynx" to fetch your page. You can make web pages that do these dynamic content displays: - Check the list of users currently on the machine. (using "who") - Send a line of text to a logged-in userid every time someone accesses or refreshes the page. (using "write") - Show the most recent 10 userids to log in. (using "last") - etc. You must not change the first two lines of output of your script; the first line of output must always be "Content-Type: text/plain" and the second line must always be empty. You can change any of the lines that follow those first two lines. Always test your CGI script from the Unix shell command line before trying it using the URL in the web browser. The web browser will not show you the standard error messages from any commands (or from commands not found); only the Unix command line will show those problems. (The standard error output goes into the system web log.) --------------------------- Error output in CGI scripts --------------------------- If you put the following line near the beginning of your script, it will redirect all standard error output produced from that line onward to the script standard output (into your web browser) instead having it get lost into the system web log: exec 2>&1 Any standard error output produced after that line will appear on standard output instead. (This is useful for CGI scripts!) Try the following script with and without the "exec" line: #!/bin/sh -u exec 2>&1 # this redirects stderr to stdout from here on down PATH=/bin:/usr/bin ; export PATH umask 022 LC_COLLATE=C ; export LC_COLLATE echo "Content-Type: text/plain" echo "" date nosuchcommand For CGI scripts that do not use "exec 2>&1", error messages must be written to standard output. (Non-CGI shell scripts must write error messages to standard error, not to standard output.) Text sent to standard error from a CGI script does not appear in the web page, unless you have redirected standard error to standard output. ------------------------------- Argument Passing to CGI scripts ------------------------------- You can pass one single command-line argument to your CGI script by appending a question mark and word to the end of your URL, e.g.: http://net2003.idallen.ca:8888/~abcd0001/cgi-bin/date.cgi?ABC The text "ABC" given by the user at the end of the URL is available inside your CGI script as argument $1 or in variable $QUERY_STRING (an environment variable set by the web server). You may use either $1 or $QUERY_STRING inside your script. (Use one or the other; don't mix things up by using both!) For example: #!/bin/sh -u exec 2>&1 PATH=/bin:/usr/bin ; export PATH umask 022 LC_COLLATE=C ; export LC_COLLATE echo "Content-Type: text/plain" echo "" date echo "The argument count is $#" echo "The argument is '$1'" Use your web browser to execute the above CGI script with and without an argument: http://net2003.idallen.ca:8888/~abcd0001/cgi-bin/date.cgi http://net2003.idallen.ca:8888/~abcd0001/cgi-bin/date.cgi?hello there ---------------------- CGI script environment ---------------------- If you print the environment variables at the end of your CGI script (using the printenv command), you will see the many variables set by the web server when it executes your script.