首页 > 其他 > 详细

bash 实现apache 的CGI 程序,并实现传入参数

时间:2014-04-06 05:46:44      阅读:1529      评论:0      收藏:0      [点我收藏+]

在网上看到好多关于apache的文章,但一直找到不关于用bash实现cgi,并且能够顺利执行自定义命令的脚本,只好亲自动手试一试,终于弄明白其中的要点,所以现在记录一下。


首先是配置apache的cgi执行环境。一般默认都是支持的,并且路径是:/var/www/cgi-bin下面。除非有更改的。

现在测试下cgi的环境: http://192.168.100.106/cgi-bin/hello.cgi

#!/bin/bash
echo -e "Content-type: text/html\n\n";
echo "<html>"
echo "<title>"
echo -e "this is shell cgi\n"
echo "</title>"
echo "<body>"
echo -e "<p> hello , andy body ..</p>"
echo "</body>"
echo "</html>"


如果能成功的话,结果输出为: hello , andy body ..


。。

现在,提高难度,使bash的cgi能接收form 的传参:

表单网页源码为:

<html>
<title>redhat6.long.com
</title>
<body>
    <h1>###################  wellcome to redhat6.long.com ##################
</h1>
    <a href="http://192.168.100.106/zabbix">zabbix</a>
    <a href="http://192.168.100.106/nagios">nagios</a>
    <a href="http://192.168.100.106/nconf">nconf</a>
    <a href="http://192.168.100.106/svn/">mysvn</a>
    <a href="http://192.168.100.106/phpMyAdmin/">phpMyAdmin</a>
    <a href="http://192.168.100.106/test.php">php</a>
    <a href="http://192.168.100.106/ks.cf">ks.cf</a>
    <p>cmd command</p>
    <form action="http://192.168.100.106/cgi-bin/cmd.cgi" method="post"> 
    Enter CMD: <input name="data" size="25"> 
    <input type="submit" value="Submit"> 
    </form>
</body>
</html>


访问显示如图:

bubuko.com,布布扣


现在开始是添加能够执行传参cgi了,这个是参照某个例子, 首先要添一个脚本到/var/www/cgi-bin目录下:proccgi.sh

#!/bin/sh
#
# Process input to a CGI script. Written and Copyright 1995 Frank Pilhofer
# You may freely use and distribute this code free of charge provided that
# this copyright notice remains.            fp@informatik.uni-frankfurt.de
#
# All variables in here are prefixed by _F_, so you shouldn‘t have
# any conflicts with your own var names
#
# get query string. if $REQUEST_METHOD is "POST", then it must be read
# from stdin, else it‘s in $QUERY_STRING
#
if [ ${DEBUG:-0} -eq 1 ] ; then
        echo --Program Starts-- 1>&2
fi
#
if [ "$REQUEST_METHOD" = "POST" ] ; then
        _F_QUERY_STRING=`dd count=$CONTENT_LENGTH bs=1 2> /dev/null`"&"
        if [ "$QUERY_STRING" != "" ] ; then
                _F_QUERY_STRING="$_F_QUERY_STRING""$QUERY_STRING""&"
        fi
        if [ ${DEBUG:-0} -eq 1 ] ; then
                echo --Posted String-- 1>&2
        fi
else
        _F_QUERY_STRING="$QUERY_STRING""&"
        if [ ${DEBUG:-0} -eq 1 ] ; then
                echo --Query String-- 1>&2
        fi
fi
if [ ${DEBUG:-0} -eq 1 ] ; then
        ( echo "  " $_F_QUERY_STRING
          echo --Adding Arguments-- ) 1>&2
fi
#
# if there are arguments, use them as well.
#
for _F_PAR in $* ; do
        _F_QUERY_STRING="$_F_QUERY_STRING""$_F_PAR""&"
        if [ ${DEBUG:-0} -eq 1 ] ; then
                echo "  " arg $_F_PAR 1>&2
        fi
done
if [ ${DEBUG:-0} -eq 1 ] ; then
        ( echo --With Added Arguments--
          echo "  " $_F_QUERY_STRING ) 1>&2
fi
#
# if $PATH_INFO is not empty and contains definitions ‘=‘, append it as well.
# but replace slashes by ampersands
#
if echo $PATH_INFO | grep = > /dev/null ; then
        _F_PATH_INFO="$PATH_INFO""//"
        if [ ${DEBUG:-0} -eq 1 ] ; then
                ( echo --Adding Path Info--
                  echo "  " $_F_PATH_INFO ) 1>&2
        fi
        while [ "$_F_PATH_INFO" != "" -a "$_F_PATH_INFO" != "/" ] ; do
                _F_QUERY_STRING="$_F_QUERY_STRING""`echo $_F_PATH_INFO | cut -d                                                                                         / -f 1`""&"
                _F_PATH_INFO=`echo $_F_PATH_INFO | cut -s -d / -f 2-`
        done
fi
#
# append another ‘&‘ to fool some braindead cut implementations. Test yours:
# echo ‘i am braindead!‘ | cut -d ‘!‘ -f 2
#
_F_QUERY_STRING="$_F_QUERY_STRING""&"
#
if [ ${DEBUG:-0} -eq 1 ] ; then
        ( echo --Final Query String--
          echo "  " $_F_QUERY_STRING ) 1>&2
fi
#
while [ "$_F_QUERY_STRING" != "" -a "$_F_QUERY_STRING" != "&" ] ; do
        _F_VARDEF=`echo $_F_QUERY_STRING | cut -d \& -f 1`
#       _F_QUERY_STRING=`echo $_F_QUERY_STRING | cut -d \& -f 2-`
        _F_VAR=`echo $_F_VARDEF | cut -d = -f 1`
        _F_VAL=`echo "$_F_VARDEF""=" | cut -d = -f 2`
#
# Workaround for more braindead cut implementations that strip delimiters
# at the end of the line (i.e. HP-UX 10)
#
        if echo $_F_QUERY_STRING | grep -c \& > /dev/null ; then
                _F_QUERY_STRING=`echo $_F_QUERY_STRING | cut -d \& -f 2-`
        else
                _F_QUERY_STRING=""
        fi
        if [ ${DEBUG:-0} -eq 1 ] ; then
                ( echo --Got Variable--
                  echo "  " var=$_F_VAR
                  echo "  " val=$_F_VAL
                  echo "  " rem=$_F_QUERY_STRING ) 1>&2
        fi
        if [ "$_F_VAR" = "" ] ; then
                continue
        fi
#
# replace ‘+‘ by spaces
#
        _F_VAL="$_F_VAL""++"
        _F_TMP=
        while [ "$_F_VAL" != "" -a "$_F_VAL" != "+" -a "$_F_VAL" != "++" ] ; do
                _F_TMP="$_F_TMP""`echo $_F_VAL | cut -d + -f 1`"
                _F_VAL=`echo $_F_VAL | cut -s -d + -f 2-`
                if [ "$_F_VAL" != "" -a "$_F_VAL" != "+" ] ; then
                        _F_TMP="$_F_TMP"" "
                fi
        done
        if [ ${DEBUG:-0} -eq 1 ] ; then
                echo "  " vrs=$_F_TMP 1>&2
        fi
#
# replace ‘%XX‘ by ascii character. the hex sequence MUST BE uppercase
#
        _F_TMP="$_F_TMP""%%"
        _F_VAL=
        while [ "$_F_TMP" != "" -a "$_F_TMP" != "%" ] ; do
                _F_VAL="$_F_VAL""`echo $_F_TMP | cut -d % -f 1`"
                _F_TMP=`echo $_F_TMP | cut -s -d % -f 2-`
                if [ "$_F_TMP" != "" -a "$_F_TMP" != "%" ] ; then
                        if [ ${DEBUG:-0} -eq 1 ] ; then
                                echo "  " got hex "%" $_F_TMP 1>&2
                        fi
                        _F_HEX=`echo $_F_TMP | cut -c 1-2 | tr "abcdef" "ABCDEF"                                                                                        `
                        _F_TMP=`echo $_F_TMP | cut -c 3-`
#
# can‘t handle newlines anyway. replace by space
#
#                       if [ "$_F_HEX" = "0A" ] ; then
#                               _F_HEX="20"
#                       fi
                        _F_VAL="$_F_VAL""`/bin/echo ‘\0‘\`echo "16i8o"$_F_HEX"p"                                                                                         | dc\``"
                fi
        done
#
# replace forward quotes to backward quotes, since we have trouble handling
# the former ones.
#
        _F_VAL=`echo $_F_VAL | tr "‘" ‘\`‘`
#
# if debug, send variables to stderr
#
        if [ ${DEBUG:-0} -eq 1 ] ; then
                ( echo --Final Assignment--
                  echo "FORM_$_F_VAR"=\‘$_F_VAL\‘ ) 1>&2
        fi
#       /bin/echo "FORM_$_F_VAR"=\‘$_F_VAL\‘
        /bin/echo "FORM_$_F_VAR"="‘"$_F_VAL"‘"
done
#
if [ ${DEBUG:-0} -eq 1 ] ; then
        echo done. 1>&2
fi
#
# done.
#
exit 0

并且添加可执行权限: chmod a+x proccgi.sh

下面是我的自定义脚本了: cmd.cgi (这个网页的表单中指定的cgi名字对应)

#!/bin/bash
# init params
eval `/var/www/cgi-bin/proccgi.sh $* 2>/tmp/proccgi.log`  ## 引入proccgi.sh ,对URL进行解释操作,重定向错误为了方便调试使用的,有可能是权限问题造成问题
# this is orgin data , is will make "/" as "\057" , "|" as "\0174"
srcdata=$FORM_data   ### $FORM_data 格式是因为在表单的数据输入框的名字是data , 按 FORM_name格式改写
data=$FORM_data
`"$data" 2>> /tmp/proccgi.log`  ##同上
                                                                                                      
function handData(){
      #  在执行“cat /etc/passwd” 的等命令,“/”传过时会变成"\057" ,所以要转义回原来的格式。
                data=`echo  "$srcdata"|sed ‘s/\\057/\//g‘| tr -d ‘\\‘ 2>/dev/null`
                data=$(echo  "$data" | sed ‘s/0174/|/p‘)
    #同理,“|” 也被转换成了"\0174" ,所以要转回原来的格式(在其它脚本可以用,在这里出问题了,不过“|”就可以了)
        # hand " , remove 042
                #data=$(echo "$data| sed )
}
handData
echo $data >> /tmp/proccgi.log  ## 方便调试
`"$data" 2>> /tmp/proccgi.log` ###方便调试
echo -e "Content-type: text/html\n";
echo "<html>"
echo "<title>"
echo -e "this is shell cgi\n"
echo "</title>"
echo "<body>"
echo -e "<h1>I am $(whoami)\t\t\n</h1>"
echo -e "<a href="http://192.168.100.106">go back</a>"
echo -e "<h2>srccmd = $srcdata , cmd = $data</h2>"
echo "<p>"
#this is ok , but it can‘t use ‘|‘ or ‘cat xxx‘ etc...
echo -e "<pre>$($data | awk ‘{print "<br>"$0"</br>"}‘)</pre>"  ##添加p , bre 等标签,可以在输出的时候可以换行
#echo -e "<pre>$(su paylm -c $data | awk ‘{print "<br>"$0"</br>"}‘ 2>/tmp/proccgi.log)</pre>"
echo "</p>"
echo "</body>"
echo "</html>"
#!/bin/bash
# init params
eval `/var/www/cgi-bin/proccgi.sh $* 2>/tmp/proccgi.log`  ## ,为了方便调试使用的,有可能是权限问题造成问题
# this is orgin data , is will make "/" as "\057" , "|" as "\0174"
srcdata=$FORM_data
data=$FORM_data
`"$data" 2>> /tmp/proccgi.log`  ##同上
                                                                                                               
function handData(){
      #  在执行“cat /etc/passwd” 的等命令,“/”传过时会变成"\057" ,所以要转义回原来的格式。
                data=`echo  "$srcdata"|sed ‘s/\\057/\//g‘| tr -d ‘\\‘ 2>/dev/null`
                data=$(echo  "$data" | sed ‘s/0174/|/p‘)
    #同理,“|” 也被转换成了"\0174" ,所以要转回原来的格式(在其它脚本可以用,在这里出问题了,不过“|”就可以了)
        # hand " , remove 042
                #data=$(echo "$data| sed )
}
handData
echo $data >> /tmp/proccgi.log  ## 方便调试
`"$data" 2>> /tmp/proccgi.log` ###方便调试
echo -e "Content-type: text/html\n";
echo "<html>"
echo "<title>"
echo -e "this is shell cgi\n"
echo "</title>"
echo "<body>"
echo -e "<h1>I am $(whoami)\t\t\n</h1>"
echo -e "<a href="http://192.168.100.106">go back</a>"
#echo "<p>$FORM_data</p>"
echo -e "<h2>srccmd = $srcdata , cmd = $data</h2>"
echo "<p>"
#this is ok , but it can‘t use ‘|‘ or ‘cat xxx‘ etc...
echo -e "<pre>$($data | awk ‘{print "<br>"$0"</br>"}‘)</pre>"  ##添加p , bre 等标签,可以在输出的时候可以换行
#echo -e "<pre>$(su paylm -c $data | awk ‘{print "<br>"$0"</br>"}‘ 2>/tmp/proccgi.log)</pre>"
echo "</p>"
echo "</body>"
echo "</html>"

添加可执行权限:chmod a+x cmd.cgi


############################# 大功告成, 测试 ################

输入命令


bubuko.com,布布扣


bubuko.com,布布扣


### 输入命令


bubuko.com,布布扣



bubuko.com,布布扣



只是执行带管道有错。








本文出自 “海无涯” 博客,转载请与作者联系!

bash 实现apache 的CGI 程序,并实现传入参数,布布扣,bubuko.com

bash 实现apache 的CGI 程序,并实现传入参数

原文:http://plong.blog.51cto.com/3217127/1391014

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!