tail -f to the web-browser
Ever wanted to pipe tail -f
to a web-page? Here’s a one liner…
On the server
$ (echo -e 'HTTP/1.1 200 OK\nAccess-Control-Allow-Origin: *\nContent-type: text/event-stream\n' && tail -f /path/to/some/file | sed -u -e 's/^/data: /;s/$/\n/') | nc -l 1234
That should all be on a single line.
In the browser
new EventSource("http://host:1234/").onmessage = ({data}) => {
console.log(data);
; }
To try it, run the above server command (changing the path and port), pop open a browser and paste the JavaScript into the developer tools console (changing the host and port).
What’s going on?
This uses Server-Sent Events (a.k.a. EventSource), a standard HTML feature. It’s not as widely known as WebSockets, but it’s much simpler. It uses vanilla HTTP to stream messages down to a browser which can process them upon arrival, without the need for polling or nasty hacks.
EventSource is supported in all major browsers (except one — betcha’ can’t guess which).
The server side command uses netcat
to listen on a port. The output of
tail -f
to is piped to netcat
which it will send to the remote TCP port on
receiving a connection. Of course the
browser won’t understand this, so the
echo
adds valid HTTP response
headers and the sed
command
converts the tail lines into valid
Server-Sent Event packets.
Should you use this?
Uhhh no, not really. It was a fun exercise.
Use it in a pinch, but there are many things wrong with it. For example, it’ll only allow a single connection. And it starts tailing before the connection is received so if you’re not expecting a connection for a while it’ll eat memory. Oh and there’s absolutely no authentication there — another browser may connect before you do.
Okay, what should I use instead?
Use websocketd.
$ websocketd --port 1234 tail -f /path/to/file