A Bash web server

Bash Web Server with Raspberry Pi GPIO

For many Raspberry Pi projects, monitoring the status of the General Purpose Input/Output (GPIO) pins is quite important.

The Raspberry Pi gpio utility is a command-line tool that can be used to read and write to GPIO pins. The readall option can be used to show the present status of all the GPIO pins.

Rather than passing the Bash commands as a string, an alternative approach is to use a Bash script and then call (sh) that file. An example script file (web_body.sh) that shows the time and then calls the gpio readall command would be:

#!/bin/bash
# web_body.sh - Show the time and
#               PI GPIO pins
date $T
echo "$(gpio readall)"

To run this script file in a Bash web server, use the following command:

while true; do { \
  echo -ne "HTTP/1.1 200 OK\r\n"; \
   sh web_body.sh; } \
  | nc -l -k -q 2 8080; \
done

Figure 3 shows the web page with the GPIO pins' time and the status.

Figure 3: Monitor Rasp PI GPIO pins.

Send GPIO Writes from the Address Bar

Client-side GET requests can be simulated on the browser address bar. For example, entering

gpio write 7 1

in the address bar sends that string to the Bash Server as a GET request.

In Figure 4, you can see that the HTTP request uses HTML encoding. In this example, a space is converted to %20.

Figure 4: Sending GET requests from the address bar.

Bash code can be added to look for specific messages. In this case, you can search for the "gpio write 7 1" or "gpio write 7 0" messages. If found, the code then executes the extracted message.

The Bash web server code now is modified to look for the "GET gpio" message and then decode any HTTP %20 characters to spaces. Next, the code parses out the string to get the GPIO message and finally executes the required command:

while true;
  do { echo -ne "HTTP/1.1 200 OK\r\n"; \
   sh web_body.sh; } | \
  nc -l -k -q 5 8080 | \
  grep "GET /gpio" | \
  sed -e 's/%20/ /g' | \
  eval $( awk '{print substr($0,6,15) }') ;
done

With the new code, the "gpio write" text entered in the address bar is executed, and the result can be seen in the web page (Figure 5).

Figure 5: Address bar request writes to a Rasp Pi GPIO pin.

Create an HTML Form

Entering commands on the command line works, but it's crude. A better way is to create an HTML Form.

The Bash web server code can remain exactly the same as in the earlier example. The original script (web_body.sh) file can be modified to output in HTML format, and three forms can be included (Listing 2). The first and second forms will define the GET actions to turn the GPIO pin on or off, and the third form will be used to refresh the page to check for GPIO changes. Figure 6 shows the client web page with buttons to turn on and off a GPIO pin. After toggling the GPIO pin, a refresh of the web page is required to see the new status.

Listing 2

Toggling a Rasp Pi GPIO Pin

#!/bin/bash
# web_body.sh - Show the time and PI GPIO pins
#             - Use HTML instead of text output
#             - Add forms for GPIO on/off, and a refresh
echo "
<!DOCTYPE html><html><head>
</head><body>
<h1>Bash Commands in a Web Page</h1>
<h2>Toggle Pin 7 On/Off</h2>
<form action='gpio write 7 0'>
 <input type='submit' value='OFF'>
</form>
<form action='gpio write 7 1'>
 <input type='submit' value='ON'>
</form>
<form action=''>
 <input type='submit' value='Refresh Page'>
</form>
<pre>
"
date $T
echo "$(gpio readall)"
echo "</pre></body></html>"
Figure 6: Bash script with HTML buttons.

The nc utility is extremely powerful, but it can be rather dangerous in that it can create back doors into your system. In this example, the code was specifically looking for the string "GET /gpio". This allows only gpio commands to be passed. However, if the code only looked for "GET /", then you could potentially pass any command string to your server.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Gemini Protocol

    Create Gemini pages to show sensor data or control a Raspberry Pi rover.

  • Gnublin

    Embedded Linux doesn’t have to be rocket science, which the Gnublin board clearly shows. If you want to learn how to read sensors, flip switches, and switch LEDs on ARM Linux, this tiny machine is perfect for your research.

  • Elixer

    The Elixir programming language on a Raspberry Pi lets you create distributed projects in just a few lines of code.

  • Kitchen Timer

    A simple kitchen helper with two timers assists budding chefs in coping with dishes that are unlikely to be ready at the same time.

  • Gnuplot

    Use Gnuplot with command-line utilities.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More

News