Bash/CGI - - HTML call to Bash script

Bash/CGI - - HTML call to Bash script

Post by Andru Luvis » Sun, 27 Apr 1997 04:00:00



[snip]

in short, you want to know how form arguments get passed to cgi's.
it's done through the environmental variable QUERY_STRING for GET
requests, and through standard input for POST (with the length passed
in CONTENT_LENGTH).  it's encoded as name=value&name=value&... and in
name and value, all non alphanumeric characters are replaced with %XX
where XX is their hex code.  interpreting this string is not easy in
straight sh or bash.  I use a gawk script of my own devising
(available at http://andru.sonoma.edu/~luvisi/) called cgiparse.awk.
you can also use cgiparse from w3c (you have to download the whole
cern server to get it, and it's in C and has to be compiled) at
http://www.w3.org/ .  You can also check out Un-cgi at
http://www.hyperion.com/~koreth/uncgi.html which is another C program
which decodes form arguments to make writing sh cgi's easier.  I'll
explain how to do this using cgiparse.awk...  for info on the others,
check their pages.  also, if anyone knows of any other resources of
this type, let me know.

cgiparse.awk works by returning a string you can eval in a shell
script in order to assign all the form arguments into environmental
variables of the form FORM_<name> (where <name> is the name of the
form argument).  so, to use it, you put:

eval `cgiparse.awk`
near the top of your sh cgi.

then, presuming you used the name "SONGSEARCH" for the form argument,
whenever you want to know what the user entered in that field, you use
$FORM_SONGSEARCH in the sh script.

Quote:> Begin BASH code
> ~~~~~~~~~~~~~~~~~~~~~~

> #!/bin/bash
> echo 'Content-type: text/html'
> echo

so far so good.

Quote:

> #  Is this the correct way to receive the string from the HTML doc?
> #  "SONGSEARCH" should be the string that Im searching for.
> read SONGSEARCH

replace this with:
eval `cgiparse.awk`

Quote:

> a=0
> numofsongs=`grep -li $SONGSEARCH public_html/lyrics/*.html | wc -l`

                       ^^^^^^^^^^^
use $FORM_SONGSEARCH, and PUT IT IN QUOTES!  you don't want anyone
putting ; or | in there and making your script do random things, do you?

numofsongs=`grep -li "$FORM_SONGSEARCH" public_html/lyrics/*.html | wc -l`

Quote:

> ### SNIP BASH SCRIPT###

> if [ $numofsongs -gt 0 ]
> then
>    cat search_hdr.txt
>    echo '<H2>Your search for ' \"$SONGSEARCH\" ' yielded '$numofsongs'

again, put it in quotes...
    echo '<H2>Your search for ' \""$FORM_SONGSEARCH"\" ' yielded '$numofsongs'

Quote:> songs.</H2>'
>    echo '<BR>'
>    echo '<BR>'
>       for i in public_html/lyrics/*.html
>          do
>          songname=`grep -li $SONGSEARCH $i | cut -c 20-`

and here...
          songname=`grep -li "$FORM_SONGSEARCH" $i | cut -c 20-`

Quote:>          grep -ih $songname public_html/alpha/*.html

and since songname contains "tainted" data, you'll want to quote
$songname too...
          grep -ih "$songname" public_html/alpha/*.html

Quote:>       done

>       cat search_ftr.txt

> ### SNIP BASH SCRIPT###
> fi
> exit 0

> ~~~~~~~~~~~~~~~~~~~~~~
> End BASH code
> ~~~~~~~~~~~~~~~~~~~~~~

> ~~~~~~~~~~~~~~~~~~~~~~
> Begin HTML code
> ~~~~~~~~~~~~~~~~~~~~~~

> ### SNIP HTML FILE###

> <FORM Method="get" Action="/home/jrr/april/findbob.cgi">
> <CENTER>
> <B>Search Function</B>
> </CENTER>
> <BR>
> Enter your search string:
> <CENTER><INPUT TYPE="text" Size=30 Name="SONGSEARCH">
> </CENTER>
> <BR>
> <CENTER>
> <INPUT TYPE=submit Size=40 VALUE="Search">
> <INPUT TYPE=reset Size=40 VALUE="Reset">
> </CENTER>
> </FORM>

the form looks good to me...

best of luck,
andru

 
 
 

Bash/CGI - - HTML call to Bash script

Post by J. Roeme » Sun, 27 Apr 1997 04:00:00


I wish looking for somebody who
can help me with a BASH/CGI question.

(If this isn't the appropriate newsgroup,
could you point me in the right direction?
Thanks!)

If you have a moment, i'd really appreciate it!
(Please don't be scared off by the length of this
post -- i'm just wordy is all  =)

I have a question regarding using
the BASH shell for a cgi script. The hard
part has been done, which is the writing
of the shell script.  The part i'm getting hung
up on is making a call to the shell script
from my html document.  Anyway, i'm hoping
you can spare the time to take a look.  
If not, I truly understand.

So, if you're so inclined, here's what's up:

I have a web site which holds the complete song
lyrics of Bob Dylan.  
( http://www.veryComputer.com/~jrr/tbob )
I wrote a script that allows the user to type in a
string and search for the lyric archive for that
string.  Pretty straight-forward grep-type stuff.  
Anyway, I got this to work just fine as a BASH
shell script.  I had the script prompt for a string.
It also outputs all the appropriate HTML code (which
is to be interpreted by the browser).

The problem:

As you can guess, i've never written a CGI program.
So, i'm having trouble figuring out how to make
the browser call the script; then have the browser
interpret the output of the script.

Note: I've been creating this search function on
my Linux box, which is NOT on a network.  After
it's all ready to go, i'll upload it to a different
machine.  So, when you see that the paths specified
in my code don't point to a cgi-bin, this is the
reason.

My questions:
  1)  How do you make the HTML document hand-off
      the string variable to the bash script?
  2)  Does my MIME statement at the head of my
      bash script look correct?
  3)  When I run this cgi program "as is", the browser
      echos the actual code of the bash script.  It
      DOES NOT interpret the programs output.
      (In fact, i'm quite sure that the program
      isn't being executed at all when called by
      the HTML file.)
  4)  Do I use a "POST" or "GET" call in the HTML
      document?

Still with me???  Hope I haven't scared you off.
I've just typed a lot of stuff describing my problem.
However, i'm certain that the answer is a simple one
for somebody who has done this stuff.

Make no mistake, I would be *very* grateful if you
can help me.  I'm really e*d at the prospect
of implementing this search function.

Thanks a 1,000,000 for any help you can give.

Regards:

Jim Roemer

~~~~~~~~~~~~~~~~~~~~~~
Begin BASH code
~~~~~~~~~~~~~~~~~~~~~~

#!/bin/bash
echo 'Content-type: text/html'
echo

#  Is this the correct way to receive the string from the HTML doc?
#  "SONGSEARCH" should be the string that Im searching for.
read SONGSEARCH

a=0
numofsongs=`grep -li $SONGSEARCH public_html/lyrics/*.html | wc -l`

### SNIP BASH SCRIPT###

if [ $numofsongs -gt 0 ]
then
   cat search_hdr.txt
   echo '<H2>Your search for ' \"$SONGSEARCH\" ' yielded '$numofsongs'
songs.</H2>'
   echo '<BR>'
   echo '<BR>'
      for i in public_html/lyrics/*.html
         do
         songname=`grep -li $SONGSEARCH $i | cut -c 20-`
         grep -ih $songname public_html/alpha/*.html
      done

      cat search_ftr.txt

### SNIP BASH SCRIPT###
fi
exit 0

~~~~~~~~~~~~~~~~~~~~~~
End BASH code
~~~~~~~~~~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~~~~~
Begin HTML code
~~~~~~~~~~~~~~~~~~~~~~

### SNIP HTML FILE###

<FORM Method="get" Action="/home/jrr/april/findbob.cgi">
<CENTER>
<B>Search Function</B>
</CENTER>
<BR>
Enter your search string:
<CENTER><INPUT TYPE="text" Size=30 Name="SONGSEARCH">
</CENTER>
<BR>
<CENTER>
<INPUT TYPE=submit Size=40 VALUE="Search">
<INPUT TYPE=reset Size=40 VALUE="Reset">
</CENTER>
</FORM>

### SNIP HTML FILE###

~~~~~~~~~~~~~~~~~~~~~~
End HTML code
~~~~~~~~~~~~~~~~~~~~~~

 
 
 

Bash/CGI - - HTML call to Bash script

Post by J. Roeme » Mon, 28 Apr 1997 04:00:00


Andru:

First off, thank you for your very informative reply.
Damn, I had no idea that it would be this involved!
Like I said, I thought the hard part would be the writing
of the bash script.  Little did I know....

Anyway, I grabbed your cgiparse.awk, and I made the changes
that you suggested (thanks for the security suggestions too).
Still, when the script is invoked by the browser, the
only thing that happens is the actual bash code is echoed
to the browser.  The script is not being executed at all --
it just becomes viewable.  Is doing a chmod +x on
my script not enough?  (I did chmod +x to cgiparse.awk too)

Suffice it to say, if my script isnt being executed, neither
is cgiparse.awk.

Here is my script, if you wouldn't mind taking a gander:
~~~~~~~~~~~~
begin script
~~~~~~~~~~~~
#!/bin/bash
echo 'Content-type: text/html'
echo

eval `cgiparse.awk`

a=0

numofsongs=`grep -li $"$FORM_SONGSEARCH" public_html/lyrics/*.html | wc
-l`
if [ $numofsongs -gt 0 ]
then
        cat search_hdr.txt
        echo '<H2>Your search for ' \""$FORM_SONGSEARCH"\" ' yielded
'$numofsongs' songs.</H2>'
        echo '<BR>'
        echo '<BR>'
        for i in public_html/lyrics/*.html
                do
                        songname=`grep -li "$FORM_SONGSEARCH" $i | cut -c 20-`
                        grep -ih "$songname" public_html/alpha/*.html
        done
        cat search_ftr.txt
else
        cat search_hdr.txt
        echo '<H2>Your search for ' \""$FORM_SONGSEARCH"\" ' was not found.'
        echo '<BR>'
        echo '<BR>'
        cat search_ftr.txt
fi
exit 0

~~~~~~~~~~~~
end script
~~~~~~~~~~~~


> [snip]

> in short, you want to know how form arguments get passed to cgi's.
> it's done through the environmental variable QUERY_STRING for GET
> requests, and through standard input for POST (with the length passed
> in CONTENT_LENGTH).  it's encoded as name=value&name=value&... and in
> name and value, all non alphanumeric characters are replaced with %XX
> where XX is their hex code.  interpreting this string is not easy in
> straight sh or bash.  I use a gawk script of my own devising
> (available at http://andru.sonoma.edu/~luvisi/) called cgiparse.awk.
> you can also use cgiparse from w3c (you have to download the whole
> cern server to get it, and it's in C and has to be compiled) at
> http://www.w3.org/ .  You can also check out Un-cgi at
> http://www.hyperion.com/~koreth/uncgi.html which is another C program
> which decodes form arguments to make writing sh cgi's easier.  I'll
> explain how to do this using cgiparse.awk...  for info on the others,
> check their pages.  also, if anyone knows of any other resources of
> this type, let me know.

> cgiparse.awk works by returning a string you can eval in a shell
> script in order to assign all the form arguments into environmental
> variables of the form FORM_<name> (where <name> is the name of the
> form argument).  so, to use it, you put:

> eval `cgiparse.awk`
> near the top of your sh cgi.

> then, presuming you used the name "SONGSEARCH" for the form argument,
> whenever you want to know what the user entered in that field, you use
> $FORM_SONGSEARCH in the sh script.

> > Begin BASH code
> > ~~~~~~~~~~~~~~~~~~~~~~

> > #!/bin/bash
> > echo 'Content-type: text/html'
> > echo

> so far so good.

> > #  Is this the correct way to receive the string from the HTML doc?
> > #  "SONGSEARCH" should be the string that Im searching for.
> > read SONGSEARCH

> replace this with:
> eval `cgiparse.awk`

> > a=0
> > numofsongs=`grep -li $SONGSEARCH public_html/lyrics/*.html | wc -l`
>                        ^^^^^^^^^^^
> use $FORM_SONGSEARCH, and PUT IT IN QUOTES!  you don't want anyone
> putting ; or | in there and making your script do random things, do you?

> numofsongs=`grep -li "$FORM_SONGSEARCH" public_html/lyrics/*.html | wc -l`

> > ### SNIP BASH SCRIPT###

> > if [ $numofsongs -gt 0 ]
> > then
> >    cat search_hdr.txt
> >    echo '<H2>Your search for ' \"$SONGSEARCH\" ' yielded '$numofsongs'

> again, put it in quotes...
>     echo '<H2>Your search for ' \""$FORM_SONGSEARCH"\" ' yielded '$numofsongs'

> > songs.</H2>'
> >    echo '<BR>'
> >    echo '<BR>'
> >       for i in public_html/lyrics/*.html
> >          do
> >          songname=`grep -li $SONGSEARCH $i | cut -c 20-`

> and here...
>           songname=`grep -li "$FORM_SONGSEARCH" $i | cut -c 20-`

> >          grep -ih $songname public_html/alpha/*.html

> and since songname contains "tainted" data, you'll want to quote
> $songname too...
>           grep -ih "$songname" public_html/alpha/*.html

> >       done

> >       cat search_ftr.txt

> > ### SNIP BASH SCRIPT###
> > fi
> > exit 0

> > ~~~~~~~~~~~~~~~~~~~~~~
> > End BASH code
> > ~~~~~~~~~~~~~~~~~~~~~~

> > ~~~~~~~~~~~~~~~~~~~~~~
> > Begin HTML code
> > ~~~~~~~~~~~~~~~~~~~~~~

> > ### SNIP HTML FILE###

> > <FORM Method="get" Action="/home/jrr/april/findbob.cgi">
> > <CENTER>
> > <B>Search Function</B>
> > </CENTER>
> > <BR>
> > Enter your search string:
> > <CENTER><INPUT TYPE="text" Size=30 Name="SONGSEARCH">
> > </CENTER>
> > <BR>
> > <CENTER>
> > <INPUT TYPE=submit Size=40 VALUE="Search">
> > <INPUT TYPE=reset Size=40 VALUE="Reset">
> > </CENTER>
> > </FORM>

> the form looks good to me...

> best of luck,
> andru

--
Spider Publishing, Inc.
http://www.spiderpub.com
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Bringing expert Web presence
development to your business.
 
 
 

Bash/CGI - - HTML call to Bash script

Post by Andru Luvis » Mon, 28 Apr 1997 04:00:00



> Anyway, I grabbed your cgiparse.awk, and I made the changes
> that you suggested (thanks for the security suggestions too).
> Still, when the script is invoked by the browser, the
> only thing that happens is the actual bash code is echoed
> to the browser.  The script is not being executed at all --
> it just becomes viewable.  Is doing a chmod +x on
> my script not enough?  (I did chmod +x to cgiparse.awk too)

you have to tell the server it's a cgi.  if it ends in .sh, you can
put this in your .htaccess for NCSA (if you're using a different
server, you'll have to see the docs on how to set file types):
AddType application/x-httpd-cgi .sh

and if it ends in .cgi:
AddType application/x-httpd-cgi .cgi

[snip]

Quote:> Here is my script, if you wouldn't mind taking a gander:
> ~~~~~~~~~~~~
> begin script
> ~~~~~~~~~~~~
> #!/bin/bash
> echo 'Content-type: text/html'
> echo

> eval `cgiparse.awk`

[snip]

oh, also, cgiparse.awk has to either be in your path or you have to
specify the full path to it in the eval.  remember, cgi's are executed
with their default directory the same as the server's, not the
directory the cgi is in, and cgiparse.awk has to be +x.

best of luck,
andru

 
 
 

1. BASH BASH BASH BASH BASH BASH BASH BASH BASH BASH

Is there a proper fixed bash on any of the FTP sites out there?

I know there bash is on the usual sites but I don't know if they are
bugged or not :(

Regards,

Neil.

--


------------------------------------| Edinburgh, EH14 2DE, United Kingdom
**Domino: There`s nothing you can do when you`re the next in line: Domino**

2. Getting CAP working...

3. Bash calls TCL, TCL calls Bash, 2nd Bash never reads input

4. traceroute for SunOS ???

5. calling CGI scripts from UNIX shell scripts->html

6. console fonts

7. Bashing bash (Was Re: bash or user error with set -e and subshells)

8. Empty ResultSet when there should be one...

9. bash-script as cgi-script

10. Problem in Calling a Perl Script from a Bash Script

11. Bash: Getting rubbish parameters when script first run in a new bash shell

12. The BASH shell and cgi-bin scripts

13. bash cgi-script prints exit codes