# Synchronous serving with netcat

This command will persistently serve its output--all hits from today on an apache server--to a browser, via netcat:

while true; do grep date +%d\\/%b /var/log/apache/access.log | nc -q1 -l -p8080; done


This is super-cool, but I have one pet-peeve with the way it works: the grep is run, and its output sits dormant until someone asks for it. This has two implications:

1. There's no way to make use of the request headers to change what's being served
2. The first request of the day will always serve yesterday's results, since the grep output has been sitting there since the last request. Two immediate requests in a row are the only way to know for certain that you're getting updated output.

My question is: Is there a way around this? I am dimly aware of crafting backpipes with mknod and so forth, but after some serious Googling and manpage-reading, I can't really figure out if there's a solution I'm not seeing due to lack of experience, or if I'm simply trying to do something that isn't feasible with the way unix pipes work.

Edit: I see in man nc that the -e switch can be used to "Execute the specified command, using data from the network for stdin, and sending stdout and stderr to the network." It goes on to explain that this only works if the GAPING_SECURITY_HOLE (lol) compile time option was enabled, which makes sense. So now I'm wondering, is this hugely insecure behavior what I'm actually trying to accomplish, or is there a safe middle ground?

Maybe doing just #2 (above) would be safe, but #1 wouldn't. Not sure yet.

Edit #2: Maybe something to do with named pipes?

-

Using nc something like this:

while 1 ; do nc -e /usr/local/bin/myscript -l -p 8080 ; done


(With your monitoring in /usr/local/bin/myscript) is a reasonable way to do this. The GAPING_SECURITY_HOLE bit is really just about someone using it to make a backdoor onto your machine (nc -e /bin/bash -l -p 12345). Hint: if they're on your machine, they can probably figure out some other way to do it. For a little security keep your GAPING_SECURITY_HOLE copy in /usr/local/bin/notnc or something.

The other answers, with named pipes and stuff, will be pain. The next easiest is probably writing a little python(your language of choice) script to do the socket work.

-
On Centos 5.5 and Kubuntu 10.04, nc doesn't have the -e option –  David V. Apr 5 '11 at 6:39

Rather than try and accomplish this in one line (very cool btw), why not break this into two tasks? Run a cron job at 00:01 to pull your log data into a new file that is then passed to netcat upon request?

-
This would be functional, but I'm really attracted to the idea of being able to do this with any arbitrary command without having to edit crontabs, etc. Also, keeping it as one single line of bash is an interesting academic exercise. Thanks for the response, though! –  Max Cantor Oct 30 '09 at 20:54

Does your nc have the -c option? It would seem to me to be slightly more secure than -e since the command is right there on the nc command line rather than in a separate script. However, the usual caveats still apply.

while true; do nc -q1 -l -p8080 -c 'grep \$(date +%d\\/%b) /var/log/apache/access.log'; done


From man nc:

    -c string     specify  shell  commands  to  exec after connect (use with
caution).  The string is passed to /bin/sh -c  for  execu‐
tion.   See  the  -e  option  if  you don’t have a working
/bin/sh (Note that POSIX-conformant system must have one).


My man page makes no mention of GAPING_SECURITY_HOLE.

-