Programming and Scripting :: CGI scripting with Bash



Started messing around with cgi on my LAN website...realized I still don't want to attempt to learn Perl or PHP so I decided to try some stuff with Bash.

I hear that Bash isn't the most secure thing to use for server side programming, but since this is a private server I thought it would be worth some experiments.

This first one is a tool to display high resolution ascii art on a web page.
I used to write individual web pages from a template so I wouldn't need to manually reduce the font size to see the image in full. That was annoying.
This script does that for me now, on-the-fly.

Newer Changes:
Added an optional external css file
No longer makes link to *.txt if no files are found
Some code cleanup
Displays filename in "not found" message
Displays directory name above links
FILENAME and REALFILE variables separated

New Changes:
Script now contains its own <pre> style, so an external style sheet is not needed.
Removed the unnecessary "this is what might be wrong" text.
Made font size and charset easily customizable.
Removed some other useless bytes here and there.

Code Sample
#!/bin/bash
# 2007 mikshaw
# cgi script to display high resolution ascii text files in a web page.
#
# Normally a text file containing a high-res image would extend far beyond
# the limits of a browser or text editor window, making it impossible to
# appreciate the image without manually setting your font to a tiny size.
# This script will display a text file condensed into a visually appealing
# space. A fairly high resolution ascii image should display nicely within
# the space of a maximized 1024x768 browser window. My tests with files of
# 500-character lines went slightly off the right side of the visible page
# using a 3pt font on a 1024x768 screen.
# Additionally, the script will search for *.txt files in the specified
# directory and build a list of links to them at the bottom of the page.
# I'm very new to cgi programing, so i welcome any suggestions or warnings.
#
# The script is summoned like this:
#
#http://www.my.host/cgi-bin/showascii.sh?dir=dirname&file=filename
#
# filename is the filename without a path. If there is no "dir",
# it will be assumed that the file is in the root of $MYSITE
# dirname is an optional subdirectory name relative to $MYSITE.
# If there is no QUERY_STRING at all, it will just build links
# from text files in the root of the $MYSITE directory.
#
# If you use an additional style sheet, take note that visual elements
# in this script are <a>, <h3>, <p> and <pre class="ascii">

# check for and split parameters
if [ -n "$QUERY_STRING" ]; then
NEWSTRING=`echo $QUERY_STRING | sed 's/&/ /g'`
varnum=1
for i in $NEWSTRING; do
varname=`echo $i | cut -d= -f1`
varvalue=`echo $i | cut -d= -f2`
# set bash variables from params
case $varname in
dir) ASCIIDIR="$varvalue";;
file) FILENAME="$varvalue";;
esac
varnum=$((varnum+1))
done
fi

### CONFIGURATION ########################
#
# the absolute path to your ascii files
MYSITE=/opt/lighttpd/lansite/www/ascii_art
# relative or absolute URL to additional style sheet (optional)
STYLE=
# font size and line height of ascii art
FNSZ=3pt
LNSZ=2.25pt
# character set
CHARSET=ISO-8859-1
#
##########################################

cat << TOP
<html><head><meta http-equiv="Content-Type" content="text/html; charset=$CHARSET">
<title>$FILENAME</title>
<STYLE type="text/css">pre.ascii { font-size: $FNSZ; padding: 0; line-height: $LNSZ; }</STYLE>
TOP
[ -n "$STYLE" ] && echo "<link href=\"$STYLE\" rel=\"stylesheet\" type=\"text/css\">"
echo "</head><body><h3>$FILENAME</h3>"
[ -n "$ASCIIDIR" ] && REALFILE="$MYSITE/$ASCIIDIR/$FILENAME" || REALFILE="$MYSITE/$FILENAME"
if [ -f "$REALFILE" ]; then
echo "<pre class=\"ascii\">"
cat "$REALFILE"
echo "</pre>"
else
echo "<p>"File \"$FILENAME\" not found"</p>"
fi
echo "<p>Text files available in this directory ($ASCIIDIR):<br>"
for i in $MYSITE/$ASCIIDIR/*.txt
do
NEWFILE=`basename "$i"`
[ -f "$i" ] && echo "[<a href=\"/cgi-bin/showascii.sh?dir=$ASCIIDIR&file=$NEWFILE\">$NEWFILE</a>] "
done
echo "</p>"
cat << END
<p><a href="/">&lt;&lt; BACK HOME</a></p>
</body></html>
END

heh, although I personally prefer PHP (you'll pick it up very quick as the syntax is very flexible), the use of bash+cgi is interesting.

One misc html comment though:
Wouldn't using
<ul>
<li></li>
<li></li>
...
</ul>
be better (esp. if you plan on using css?)

The </li> closing tag is optional, acording to the html documents I've read.  I have no idea how the closing tag might affect css, though, as you mentioned...I've never styled lists specifically. The </br> tags were already in there before i thought it would look better as a list, and I simply forgot to remove them. They're now removed from my local copy, thanks. I'll probably put </li> tags in just to be thorough.

I'll eventually save one of the generated pages and check the syntax against strict html, but for now I'm thinking more about its functionality than anything else...I want to try some other ways to make it less site-specific, and basically just fool around with it until i get bored and look for a new project.

I'm working on (or planning, anyway) a stripped down version of this script that will use a URL as a query string and load that instead of needing a local file. I think this would be more portable, considering many website owners probably don't run their servers on their own machines. It makes it difficult to use a full directory path if you don't know what the path is.
Maybe it isn't all that difficult, though...i'm sure if you need the path, and have permission to run scripts on your server, you could probably at least get the path to cgi-bin and work from there...

Anyway, I have no idea how to use the contents of a URL as part of an html document, so it might not happen =op

Here's another one....very simple and needs some work to make it more flexible and look better.
This script displays a random image from a directory and a button to load a new random image.
Code Sample

cat << BEGIN
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Random Image</title>
</head><body>
<form action="/cgi-bin/rand_image.sh">
<input type=submit value="random image">
</form>
BEGIN

# url to directory
PIC_URL='/rand_images'
# full path to same directory
PIC_DIR='/opt/lighttpd/lansite/www/rand_images'

# this needs some work. it assumes all files are images
num_pics=`ls -A "$PIC_DIR/" | grep -c .`
list_pics=`find "$PIC_DIR/"`
pic_array=($list_pics)
rand_image="${pic_array[$((RANDOM%num_pics))]}"
echo "<img src=\"$PIC_URL/`basename $rand_image`\"></body></html>"

Next Page...
original here.