36 comments

[ 4.5 ms ] story [ 87.6 ms ] thread
not to be that guy, but that's

1. hardly a web server

2. hardly pure bash

of course writing a server of anything in pure bash is a tad bit difficult, as opposed to a client - bash can connect(), but can't bind() / listen() nor accept() unless, of course, you use something to expose these syscalls, but that opens a whole another can of worms...

> but that opens a whole can of worms

Someone has actually went that far: http://ctypes.sh/.

Thank you! I've been searching for something like that.
> Does it work on Windows?

> Of course not.

It works just fine on Windows 10 with WSL.

Works on Cygwin as well if you have netcat installed.
I think the point here is to demonstrate that one might think that web servers are mystical beasts (true) but after all, they "just" return a HTTP header and some content.
It doesn't demonstrate that very well, then. This simply delegates all of the basic server responsibilities to netcat. Where do you draw the line between 'bash web server' and simply invoking another program?
I didn't know about netcat before, so I'd draw the line exactly here :)
Five lines seems like much when you consider that one can write a concurrent (using threads) C webserver in 12...
Do you have a link to the 12 line server?
Considering C has the semicolon, you can probably write it in less than 5 because you can put almost anything on a single line.
Bash also has a semicolon. This script could be done in two lines. Or even one if you omit the shebang.
What if you remove the audio jack?
That was both funny and disappointing. I thought it world at least serve static files. Putting netcat in a for loop is hardly a web server in bash.
Many people here fail to realize, this is an excellent debugging server. I used to have a server to print out the body and headers of requests when building an api to make sure things were going (the right headers and request body) out as expected https://github.com/minhajuddin/httpdebug/blob/master/app.go.

This is a much lighter and nicer version. This is going into my ~/bin/httpdebug :)

You can try sending a few curl requests to see that this really prints the headers and body.

    curl -H "api-key: Foo" -X POST --form name=Khaja http://localhost:8080/
Maybe I'm misunderstanding by why not just have your server have a a request logging middleware that respects some log level environment variable?
> Is this a thread based server, or does it use an event loop instead?

> No.

Well, which is it ?

Neither, its using netcat + -l flag, which is (possibly) waiting for a connection using blocking networking IO.

It can only accept one connection at a time because of the netcat command being used in a loop

Oh OK.

Well, anyone can write that in a handful of lines in most languages.

Bash (shell-script) is a very powerful language, but a bit too complicated for the non-programmer (computer hacker). Then we got Perl, but it is also a bit too complicated. Now we have JavaScript doing the same thing, but also JavaScript (ES6) is now getting more complicated. I wonder is there a rule that says a (scripting) language for non-programmers will eventually either die or end up being too complicated for non-programmers ?
For me the scripting language for non-programmers looks more like Automator (the GUI) or Workflow - its iOS counterpart.

A programming language will always be for programmers or at least enthusiasts.

Also I do not agree that bash is good for non-programmers. In order to make any more complicated thing work you have to learn a lot of syntax and language specific things. I have always found perl easier than bash to do anything remotely more complicated.

Never heard "Build a system that even a fool can use and only a fool will want to use it." ?
A small amount of pessimism is healthy, but something being really simple is often preferable. A key here is good abstraction. Take for example a file system, witch is very easy to use, but still useful for computer experts.
Clickbait - A web server in one line of bash:

    $ nginx
And the HTTP client:

    exec 3<>/dev/tcp/localhost/8080
    echo -e "GET / HTTP/1.1\n\n" >&3
    cat <&3
So this is babys first netcat server? Someone is overly proud of using a command like it was intended...
This reminds me a lot of Certbot's use of the Python SimpleHTTPServer:

  $(command -v python2 || command -v python2.7 || command -v python2.6) -c
  "import BaseHTTPServer, SimpleHTTPServer;
  s = BaseHTTPServer.HTTPServer(('', {port}), SimpleHTTPServer.SimpleHTTPRequestHandler);
  s.serve_forever()"
Out of curiosity. What is wrong with: python -m SimpleHTTPServer ?
It was my understanding that you cannot change the host or port when invoking SimpleHTTPServer that way.
(comment deleted)