68 comments

[ 3.1 ms ] story [ 131 ms ] thread
Neat trick, but probably too limited to be of much use. Also, stopping it is kind of a nuisance.
Why? It only takes one ^C
For me, it doesn't even respond to ^C (or even ^\). I had to ^Z it, and then `kill %1`.

Could be an OS-dependent thing. I'm using OS X.

Indeed. It could use in front of while loop something like:

int_cmd(){exit 1;}trap 'int_cmd' 2;

If you have python, then these are really useful, just serves up the current directory.

  Python 2.x:
  python -m SimpleHTTPServer

  Python 3.x:
  python -m http.server 8000
Easier to remember, plus Python is probably more likely to exist on a given machine than netcat.
This is still my go-to solution, though I couldn't help but to share when I found the other solution.
(comment deleted)
Or for https (e.g. when developing for Chrome's speech recognition API):

    twistd --nodaemon web --path=. -c snakeoil.crt -k snakeoil.key --https=8443
And to generate a 100-year localhost key/cert for use with this:

    openssl genrsa -passout pass:dummy -out snakeoil.secure.key 1024
    openssl rsa -passin pass:dummy -in snakeoil.secure.key -out snakeoil.key
    openssl req -new -subj "/commonName=localhost" -key snakeoil.key -out snakeoil.csr
    openssl x509 -req -days 36500 -in snakeoil.csr -signkey snakeoil.key -out snakeoil.crt
Or:

    cat /etc/certs/ssl-cert-snakeoil.pem \
        /etc/priv/ssl-cert-snakeoil.key >> \
        /etc/priv/ssl-cert-and-key-snakeoil.pem
    chmod og-rwx /etc/priv/ssl-cert-and-key-snakeoil.pem
    #note instructions above on how to generate a fresh
    #self-signed cert
    python3 -m http.server 8000 &
    stunnel -p /etc/ssl/private/ssl-cert-and-key-snakeoil.pem -r 8000 -d 4430
Which does require stunnel, in addition to python, obviously.
I can't edit my original comment now, but thought I should add this for cleanup after key/cert generation:

    rm snakeoil.secure.key snakeoil.csr
> As root you can run:

Unless the specified 'index.html' is only readable by root, you don't have to be root to run that.

Only the low ports are restricted from regular users.

Quite interesting, specially with the limitations of the file:// protocol
(comment deleted)
We've used a similar trick to copy files between coworkers:

  on server: while true; nc -l $PORT < $FILE; done
  on client: nc $SERVER $PORT > $FILE
Quick, simple and easy to fire up. You can continue to hack on the file and nc will serve up the latest saved version.
Is your while loop missing a "do" statement, or am I missing something?
$ busybox httpd

Works even in an initramfs, and in some embedded systems. Serves up the current directory, and you can even have CGI scripts in cgi-bin.

Thanks! I'd forgotten about busybox, but that's often how your home router is doing things.

* Side note: if it is, make sure your router manufacturer provides the GPL source release.

I dont think they usually use it as the web server, as they need some scripting not static pages only. The smallest server I know of that can do cgi is webfsd).
Hmm, there's another investigation to do.
Woah, I didn't realize busybox had an httpd. Truly a sweet piece of software.
It often won't, as features ("applets") are chosen at compile-time.
Adding my two cent:

    twistd web --path . --port 8080
That's not a one-line script. That's a multi-line script with the linebreaks removed.
I suggest you don't say things like that around Perl programmers.
Most Perl one-liners don't have semicolons.
The language lends itself to that, but as far as I am aware there is no prejudice against Perl one-liners that do contain semicolons.
It is 85 characters long. Strip some spaces from it, and it qualifies as a one-liner.
Since nobody mentioned ruby version

ruby -run -e httpd . -p 5000

If you have node-static installed.

  npm install -g node-static
  # serve up the current directory
  $ static
  serving "." at http://127.0.0.1:8080
More at https://github.com/cloudhead/node-static
(comment deleted)
I remember trying to write a web server that can respond to requests in bash, several years ago. Since it didn't have sockets support that part was going to be handled by netcat. The problem I ended up with was that bash couldn't read and write to the same pipe. The mkfifo solution was the closest that I got to. It turns out that ksh was perfectly capable of reading and writing to the same pipe at that stage. Not long after I got stuck with bash, awk started to support sockets so I used that. Then bash started to support sockets, and many more features, so I suspect it's possible to write a solution in bash now that doesn't need netcat, but might still need a fifo.
Since everyone uses the one line of bash to just start their favourite complex network utility, I'll also contribute mine:

while true; sudo /usr/sbin/apachectl start; break; done;

I came to this thread to post the exact same joke.
That's nothing. I made a webserver with just two keystrokes: control-C, control-V. You do have to have Apache installed though.
And, for the sake of accuracy, the proper bash syntax would be:

  while true; do sudo /usr/sbin/apachectl start; break; done;
netcat is the most handy service I have seen on Linux. Any more like this?
Look into Socat. Socat is to netcat as Vim is to vi.
Nice. However:

    $ curl localhost:8080 & curl localhost:8080
    <!doctype html>
    [...]
    curl: (7) Failed connect to localhost:8080; Connection refused
Yes, the server "restarts" after each request, and during the restart, it's not listening.

That's not what I would call a "server".