Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1628251
  • 博文数量: 185
  • 博客积分: 10363
  • 博客等级: 上将
  • 技术积分: 2205
  • 用 户 组: 普通用户
  • 注册时间: 2006-01-11 22:29
文章分类
文章存档

2013年(12)

2012年(5)

2011年(2)

2010年(12)

2009年(9)

2008年(15)

2007年(48)

2006年(82)

分类: LINUX

2009-11-12 15:41:09

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.

#!/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:

#!/bin/sh
echo "Content-type: text/html\n"

# our html code
echo ""
echo "My FOX page"
echo ""
echo "

Welcome to my FOX Board web page

" echo "Hello World !" echo " " echo ""

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:

#!/bin/sh
echo "Content-type: text/html\n"

# our html code
echo ""
echo "reboot"
echo "

reboot

" echo "" /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.

#!/bin/sh
echo "Content-type: text/html\n"

# our html code
echo ""
echo "Hello CGI"
echo ""
echo "
"

# print out the environment settings
/usr/bin/env

echo "
" echo "" echo ""

My output looks like this when I call

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.
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 .

Lets try using this source:

#!/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 ""
echo "Hello CGI"
echo ""
echo "the value of ID is $ID
" echo "the value of TEXT is $TEXT
" echo "" echo ""
And calling it by .

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.

#!/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 ""
echo "Hello CGI"
echo ""

# test if any parameters were passed
if [ $ID ] && [ $TEXT ]
then
  echo "The parameters were set 
" echo "the value of ID is $ID
" echo "the value of TEXT is $TEXT
" else echo "
" echo "ID :
" echo "TEXT :
" echo "TEXT : " echo "
" fi echo "" echo ""

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.

#!/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 ""
echo "Hello CGI"
echo ""


# test if any parameters were passed
if [ $CMD ]
then
  case "$CMD" in
    ifconfig)
      echo "Output of ifconfig :
"
      /sbin/ifconfig
      echo "
" ;; uname) echo "Output of uname -a :
"
      /bin/uname -a
      echo "
" ;; dmesg) echo "Output of dmesg :
"
      /bin/dmesg
      echo "
" ;; ls) echo "Output of ls $FOLDER :
"
      /bin/ls "$FOLDER"
      echo "
" ;; *) echo "Unknown command $CMD
" ;; esac fi # print out the form echo "Choose which command you want to run" echo "
" echo " ifconfig
" echo " uname -a
" echo " dmesg
" echo " ls -- folder
" echo "" echo "
" echo "" echo ""
阅读(2534) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~