Some other cool guy wrote this (https://github.com/tlrobinson/wwwoosh) sinatra framework in bash. I am using it to control the lights in my house with my phone.
A very simple js frontend sends get requests to wwwoosh, and some bash commands get executed to control a relays board that turns the lights on and of.
It's very simple, consumes almost no memory and is very reliable.
How about ddshttpd (http://dd-sh.intercal.org.uk/web-server/)? A web server written using only sh(1), dd(1), and echo(1). It even supports running server side scripts ("ddsh-bin") and setting content type based on file extension.
I'm somewhat saddened to see that they don't own dd.sh domain anymore. It was at least twice as cute as no.de is :)
I went to university (Edinburgh) with the author of dd.sh. I remember him as a crazy Italian in the classic mold. As a first-year undergraduate in the computer science department he convinced me to forkbomb the department's main 30-way computer server. What he didn't mention was that the head of department was running a bunch of stuff on there at the time. My resulting heart rate was eclipsed only by the load average on the host, which if memory serves pegged at 512. Now I knew how the sorcerer's apprentice felt.
In a demonstration of genius he then proceeded to shutdown this particular forkbomb, using - you guessed it - only dd and sh ...
You should clean the data from the user before passing it to the shell. There is a trivial remote command execution vulnerability in the URL ("echo 'GET /;$(cat /etc/passwd)'|nc ..."). I assume there are more.
You shouldn't have to sanitize if you quote your variables properly. If general, the rules for "$foo" are "parse first, expand afterwards" while those for $foo are "parse, expand, parse again", so
foo="hello world"
echo $foo # prints "hello world" [2 arguments]
echo "$foo" # prints "hello world" [1 argument]
Note that you can't trivially inject a command this way, though you can inject arbitrary arguments:
foo="; ls"
echo $foo # prints "; ls"
I would recommend never using test ([) with more than three arguments. Once you start doing -a and -o, then people can inject confusing values for variables, making it impossible to parse:
foo='!'
bar='2'
[ "$foo" = 1 -a "$bar" = 2 ] # -bash: [: too many arguments
Since test runs a subprocess, it can't tell the difference between data and arguments. Instead, you should do something like this:
foo='!'
bar='2'
[ "$foo" = 1 ] && [ "$bar" = 2 ]
(This also has the advantage of being way more legible.)
Why not using /bin/sh? Didn't saw a bash specific tool (except the function syntax which is easy to convert). And if you really want to use bash, please use #!/usr/bin/env bash so that it is more compatible.
It's likely I'll want to do some more complex stuff in bash, rather than pure sh. My preferred shell is zsh but of the more advanced shells, bash is the most prevalent.
I've pushed the change to use /usr/bin/env bash :-)
FreeBSD for example does not have bash installed by default since bash is not part of FreeBSD operating system and when it is installed (using ports or packages) it's installed into /usr/local where all other 3rd party software is installed.
Some systems use /bin and /sbin as directories containing binaries capable of being used in single-user mode (where only / is mounted), meaning a pretty bare experience. root's shell would probably not be bash in this case and bash would probably be optional/a package and would be installed elsewhere.
I don't think they are useless. They keep the 'mystery' out of web servers. It is self limiting for folks when they see a piece of software and think of it as an impenetrable wall which cannot be breached or changed.
I proposed an internal web api at work for some hardware that needed to call out and test an address against a database of known problems. The initial response was the pain of setting up the infrastructure of a web server just for this one thing, was "huge" except it isn't really huge, its like 12 lines of perl or python code. People need to know that you can do that to see the pocket web server as a neat solution.
completely disagree. Want to create a quick file server to test a design or an html page in a browser? Yes you could use python SimpleHTTP but python is a dependency that not all times we have access too.
People might say that this is utterly useless, but actually in one big companies I worked for we had something like this (not really http but still bash server) to execute and control tests running on the machine. The beauty of the bash is that runs on 100% clean servers which is great for product testing.
This is an interesting novelty, but it can't ever be used in the real world, no matter how far along it gets, because bash is much more susceptible to security holes than normal programming languages.
There are many benefits to projects like this.
I would argue that this thread is the biggest benefit - people are sharing knowledge on shell scripting, and I'll bet you one hamburger that at least 5 people learn something new as a result.
That makes it worth it :-)
It also gets people thinking, being creative and doing something "fun". Sometimes you just have to do fun things and see where they lead.
"Yes, but", it's kind of unfortunate that at the time of writing your comment is placed next to a comment by y0ghur7_xxx, who is actually using a bash based web server to control lights with his iPhone. It's hard to argue that this is not 'real life'. On the other hand, you are right.
It depends where you draw the line.
CGI's were passed many variables and an environment by the web server.
In that respect, this is closer to a web server - the only thing it doesn't handle is the very lowest level network listening.
>the only thing it doesn't handle is the very lowest level network listening.
Which makes it a bit imprecise to call it a web server made with bash (as it requires netcat). I clicked on the title already wondering how would it be possible to open a socket with bash only.
A very simple js frontend sends get requests to wwwoosh, and some bash commands get executed to control a relays board that turns the lights on and of.
It's very simple, consumes almost no memory and is very reliable.