FOX Board LX832 is discontinued
To be informed about its availability and prices please CONTACT US
To know more about the new FOX Board G20 GO HERE
Create a GCI using bash scripting
written by the John Crispin
In this article you can learn the basics of writing simple CGI scripts in bash
Bash shell is the easiest way to create a simple CGI. The script is setup like any other
bash code. Within it you can use the full potential of bash. However, when creating CGIs,
we need to always start with the following line, so the web browser knows how to interpret
the data we are sending him.
| cgi1.sh  |
#!/bin/sh
echo "Content-type: text/html\n"
|
Once the content type has been set correctly, we can start assembling our html code.
An html "Hello World !" would look like this:
| cgi2.sh  |
#!/bin/sh
echo "Content-type: text/html\n"
# our html code
echo "<html>"
echo "<head><title>My FOX page</title></head>"
echo "<body>"
echo "<h1>Welcome to my FOX Board web page</h1>"
echo "Hello World !"
echo "</body>"
echo "</html>"
|
The next example shows how to execute standard bash commands from within the cgi.
The following script will reboot the fox when it is called by the web browser:
| cgi3.sh  |
#!/bin/sh
echo "Content-type: text/html\n"
# our html code
echo "<html>"
echo "<head><title>reboot</title></head>"
echo "<body><h1>reboot</h1></body>"
echo "</html>"
/sbin/reboot
|
This is still a very boring example though. Lets find out, how the CGI stuff actually works.
Our script is called by the httpd server (Boa in this case). In order to pass configuration
data to the script, boa sets the values of a number of pre defined environment variables.
Let find out which ones are set, when a script is run. As already mentioned, inside a bash cgi,
we can use any command available inside bash. The normal way of reading environment variables
is to use the ./env command, so we simply embed this in our script.
| cgi4.sh  |
#!/bin/sh
echo "Content-type: text/html\n"
# our html code
echo "<html>"
echo "<head><title>Hello CGI</title></head>"
echo "<body>"
echo "<pre>"
# print out the environment settings
/usr/bin/env
echo "</pre>"
echo "</body>"
echo "</html>"
|
My output looks like this when I call http://192.168.0.90/cgi/cgi4.sh?id=1&text=abc
GATEWAY_INTERFACE=CGI/1.1
HTTP_ACCEPT_CHARSET=ISO-8859-1,utf-8;q=0.7,*;q=0.7
REMOTE_ADDR=192.168.45.100
QUERY_STRING=id=1&text=abc
REMOTE_PORT=53580
HTTP_USER_AGENT=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.4) Gecko/20060508 Firefox/1.5.0.4
DOCUMENT_ROOT=/usr/html
HTTP_HOST=192.168.45.90
REQUEST_URI=/cgi/s2.sh
SERVER_SOFTWARE=Boa/0.94.14rc20
HTTP_CONNECTION=keep-alive
PATH=/bin:/usr/bin
HTTP_ACCEPT_LANGUAGE=en-us,en;q=0.5
HTTP_KEEP_ALIVE=300
SERVER_PROTOCOL=HTTP/1.1
HTTP_ACCEPT_ENCODING=gzip,deflate
REQUEST_METHOD=GET
SERVER_ADDR=192.168.45.90
SERVER_ADMIN=
PWD=/mnt/flash/etc/httpd/cgi
SERVER_ROOT=/etc/httpd/conf
SERVER_PORT=80
SCRIPT_NAME=/cgi/env_test
SERVER_NAME=192.168.45.90
Look closer at the line:
QUERY_STRING=id=1&text=abc
This is used by Boa to pass the parameters I have just handed over the web server on to the cgi.
http://192.168.0.90/cgi/cgi4.sh?id=1&text=abc
In order to process these, we need to do some ugly bashing of the environment string.
ID=`echo "$QUERY_STRING" | sed -n 's/^.*id=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"`
TEXT=`echo "$QUERY_STRING" | sed -n 's/^.*text=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"`
WHAT IS THIS ?!?!? It is actually easier than it looks :-)
The first line parses a numeric parameter and save it in the environment variable ID.
The second line parses an alpha-numeric parameter and save it in the environment variable TEXT.
Let me explain step by step:
- echo "$QUERY_STRING" | sed
send the value of $QUERY_STRING to sed
- sed -e 's/^.*id=\([^&]*\).*$/\1/'
cut out only the value of "id="
- sed -e 's/^.*text=\([^&]*\).*$/\1/'
cut out only the value of "text="
- sed "s/%20/ /g"`
replace the html escaped %20 for spaces
You do not really need to worry about these to much, just copy & paste them as needed. To know more
about the sed command go to this link.
Lets try using this source:
| cgi5.sh  |
#!/bin/sh
echo "Content-type: text/html\n"
# read in our parameters
ID=`echo "$QUERY_STRING" | sed -n 's/^.*id=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"`
TEXT=`echo "$QUERY_STRING" | sed -n 's/^.*text=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"`
# our html code
echo "<html>"
echo "<head><title>Hello CGI</title></head>"
echo "<body>"
echo "the value of ID is $ID<br>"
echo "the value of TEXT is $TEXT<br>"
echo "</body>"
echo "</html>"
|
And calling it by http://192.168.0.90/cgi/cgi5.sh?id=123&text=abc.
I told you that it is easier than what it looks like. But let's try using these to create some real control structures. The following script has two possible paths of execution. The first one prints out a html form, that the user can fill out and send back to the FOX Board. If the CGI is called, with filled out form data, it will go through the second path of execution.
| cgi6.sh  |
#!/bin/sh
echo "Content-type: text/html\n"
# read in our parameters
ID=`echo "$QUERY_STRING" | sed -n 's/^.*id=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"`
TEXT=`echo "$QUERY_STRING" | sed -n 's/^.*text=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"`
# our html code
echo "<html>"
echo "<head><title>Hello CGI</title></head>"
echo "<body>"
# test if any parameters were passed
if [ $ID ] && [ $TEXT ]
then
echo "The parameters were set <br>"
echo "the value of ID is $ID <br>"
echo "the value of TEXT is $TEXT <br>"
else
echo "<form method=get>"
echo "ID : <input type=text name=id><br>"
echo "TEXT : <input type=text name=text><br>"
echo "TEXT : <input type=submit>"
echo "</form>"
fi
echo "</body>"
echo "</html>"
|
We just wrote our first bash based CGI that actually does something half reasonable. Let's look at a more complicated example that does a certain action based on the actual value of the parameter. The following example gives the user a number of radio buttons. Depending on which one was set, a different command is executed. You will also learn how to use the case construct inside a bash script.
| cgi7.sh  |
#!/bin/sh
echo "Content-type: text/html\n"
# read in our parameters
CMD=`echo "$QUERY_STRING" | sed -n 's/^.*cmd=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"`
FOLDER=`echo "$QUERY_STRING" | sed -n 's/^.*folder=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"| sed "s/%2F/\//g"`
# our html header
echo "<html>"
echo "<head><title>Hello CGI</title></head>"
echo "<body>"
# test if any parameters were passed
if [ $CMD ]
then
case "$CMD" in
ifconfig)
echo "Output of ifconfig :<pre>"
/sbin/ifconfig
echo "</pre>"
;;
uname)
echo "Output of uname -a :<pre>"
/bin/uname -a
echo "</pre>"
;;
dmesg)
echo "Output of dmesg :<pre>"
/bin/dmesg
echo "</pre>"
;;
ls)
echo "Output of ls $FOLDER :<pre>"
/bin/ls "$FOLDER"
echo "</pre>"
;;
*)
echo "Unknown command $CMD<br>"
;;
esac
fi
# print out the form
echo "Choose which command you want to run"
echo "<form method=get>"
echo "<input type=radio name=cmd value=ifconfig checked> ifconfig <br>"
echo "<input type=radio name=cmd value=uname> uname -a <br>"
echo "<input type=radio name=cmd value=dmesg> dmesg <br>"
echo "<input type=radio name=cmd value=ls> ls -- folder <input type=text name=folder value=/mnt/flash><br>"
echo "<input type=submit>"
echo "</form>"
echo "</body>"
echo "</html>"
|
|