I'm trying to trigger a beep on the PC speaker for every unique visitor of a website.
After some brainstorming, it seemed to be possible with one line:
for e in `ssh me@mymachine "tail -n 1 -f /var/log/apache2/test.log | awk '{print $1}' | uniq"`; do beep; done
However uniq doesn't output anything as long as stdin is open (seems to wait for EOF). The same goes for the for loop. If I remove the uniq from the chain, I still get no output with tail keeping the pipe open.
This seems not to be because of buffering. Even if I write >100.000 lines into the test file with this command running, there's no output on the other end.
Is there a way to get that working without completely killing the beauty (simplicity) of the solution?
Update
I solved the first part. uniq is unblocked by prefixing the tail command with stdbuf -oL -eL
(see https://unix.stackexchange.com/a/25378/109296).
The same doesn't work for the loop.
Update 2
I got it working - but not exactly according to my spec and with 2 lines:
while [ 1 -eq 1 ]; do ssh root@speedy "stdbuf -oL -eL tail -n 1 -f /var/log/apache2/www.access.log | stdbuf -oL -eL grep 'GET / '"; sleep 60; done > www.log
awk '{print $1}'
is missing because it didn't work inside this construct (just passed through the whole line). I don't know why. But I can live without, because anyway
uniq
turned out not to be so useful after all, because it only looks at adjacent lines, which means that the requests patterns ip1, ip2, ip1 would still let ip1 through twice.
uniq -u
would do what I expect, but it has the same problem like sort
: doesn't output anything as long as stdin is open (not even with stdbuf -oL
.
This command just writes all requests for the base URL (/) to another file. I wrapped it into a loop (and wait) in order to have it automatically retry if for some reason the pipe or connection interrupts.
while inotifywait -e modify www.log; do beep -f 250; done
makes the sound! I could not get the bash for loop to process line by line unbuffered, also tried while read
with the same result.
Thus I gave up and went on with inotifywait
which however means that I need an intermediate file (maybe a named pipe would also work, didn't try. Doesn't really make a difference for me).
I'd still be thankful to contributions which help to make the filtering of unique visitors work (without escalating complexity).
This will be a nice surprise for my team members when they return to the office :-)
I plan to extend this notification system to monitor several events, using different audio frequencies. That's the best job I've found so far for an old server collecting dust...
ar
.tsort
could be worthwhile as well. – mikeserv Apr 06 '15 at 05:54MAILFILE=/var/log/apache2/www.access.log%$(beep)
which will get the shell to watch the file for modification and expand the%
user-specified message every time it does. – mikeserv Apr 06 '15 at 08:35stdbuf
cmd seems to solve that, however some tools (like sort) really wait for EOF (which makes sense). Your proposal to make the shell watch for modifications is unknown to me. I couldn't get it working (executes the cmd once and then exits). Can you provide me with a link to a documentation of that feature? – didi_X8 Apr 06 '15 at 14:32sort
blocks: how else can it sort its input? You aren't asking for something simple. You could hide most of the complexity into a program that takes its input, checks it against a DHT on a cluster somewhere, then writes out a line if your identifier wasn't found in it yet. Would that still be beautful and simple and majestic? – badp Apr 06 '15 at 20:42tail -f /.../access.log | perl -naE '/GET/ and ($a{$F[0]}++ == 0) and say $F[0] and ``beep`` '
– JJoao Apr 07 '15 at 16:38$MAILPATH
and I didn't even bother to quote it right:MAILPATH
='/path/to/file%$(some command executed at mod time)'
. MAILPATH ...a list of pathnames and optional messages separated by colons. If ... set, the shell shall inform the user if any of the files named by the variable are created or if any of their modification times change. Each pathname can be followed by '%' and a string that shall be subjected to parameter expansion and written to standard error when the modification time changes. – mikeserv Apr 08 '15 at 03:06ar
orranlib
. These are the kinds of tools developers use to build out linked library archive files because they can be searched quickly according to specified order. Doinfo ar
orinfo tsort
. – mikeserv Apr 08 '15 at 03:10