Wednesday, November 17, 2010

setting up IIS to use shell scripts as CGI scripts

Because I'm old school and love shell scripts, I wanted to kick off a shell script from my web browser. In this case, my shell script would sort through a text file, use gnuplot to output a graphic as a png and then display the script in the browser.

Setup IIS to execute shell scripts
I won't belabor how to setup your web server to execute shell scripts, as the link below Installing CGI Applications in IIS 6.0 explains most of the steps. However, I will call out one caveat that was tricky to setup. I use Cygwin to write my shell scripts, so I wanted IIS to use Cygwin's sh.exe as the shell script command interpreter. The nut here is that I needed to add a special configuration in order to have IIS execute Cygwin's script interpreter. Here's how to do this.
  • right-click on the cgi folder
  • click Properties
  • select the Virtual Directory tab
  • click Configuration
  • click Add and type the following:
C:\cygwin\bin\sh.exe "%s" "%s"

Create a Simple Shell Script as a CGI
It is useful to setup a simple script in order to test that IIS is calling sh.exe properly. Here is mine:
#!/bin/sh
echo "HTTP/1.0 200 OK"
echo "Content-type: text/html"
echo
echo "<HTML><HEAD><TITLE>environment variables test</TITLE></HEAD>"
echo "<BODY>"
/usr/bin/env ¦ /usr/bin/sort
echo "</BODY></HTML>"
exit


Remember that this script is essentially hand-rolling an HTTP response. Breaking it down:
1. Send the header:
echo "HTTP/1.0 200 OK"
echo "Content-type: text/html"


2. Make sure you send a blank line (\n\r )
echo

3. After the header and the blank line, send out well-formed HTML
echo "<HTML><HEAD><TITLE>environment variables test</TITLE></HEAD>"

4. Plop some shell functions in there to verify that sh.exe is interpreting commands correctly. In this example, I am printing out and sorting the results of the "env" command. The "env" command prints out the IIS working set of environment variables. Make sure to put the full path in your command string:
/usr/bin/env ¦ /usr/bin/sort

5. Close your HTML
echo "</BODY></HTML>"

6. Exit the script
exit

Reference the script in the HTML of a test page:
<a href="/cgi-bin/env.sh">click me</a>

Here is the output of the script


This is a very simple script, but you can see that the sucker works. As it took a good two hours of finagling, I thought it worthwhile to post these instructions and links to further reading.

My gnuplot script is much more involved. If interested, drop me a line and I can send you that script or maybe post another blog article about how to create it.

Good luck!
TAG

References
Common Gateway Interface (CGI)
Short list of HTTP status codes
Installing CGI Applications in IIS 6.0
Writing CGI Scripts for a Web Server
Feel free to drop me a line or ask me a question.