You are not logged in.
Pages: 1
I am writing a script that will watch everything.log, then eventually will pipe it's output to dzen2. Here is my script so far.
gary@Lister ~ $ cat .bin/alerts
#!/bin/bash
log()
{
tail -n 1 /var/log/messages.log
}
while true; do
if [ `log | grep -E 'mounted /dev/sdd' -c` -ge 1 ]; then
MESG="xd card mounted"
elif [ `log | grep -E 'unmounted /dev/sdd' -c` -ge 1 ]; then
MESG="xd card unmounted"
fi
echo $MESG
done
You can probably see my grep problem the first if line matches mounted and unmounted lines. Damm. I'm sure you guys can help a guy who struggles with bash put this one to rest
Offline
you could make your grep more specific, match on '^mounted' or ' mounted' so you don't catch 'unmounted' as well.
but the smarter way is probably to just reverse your if statement. check for 'unmounted' first, that'll fail on just 'mounted' which would be caught in the elif.
i'd also recommend -qF for this:
#!/bin/bash
log() { tail -n 1 /whatever; }
while true; do
# i'll put the sleep up top so i can just use `continue` when
# our hook does catch and it'll still wait before checking again
sleep 1
if log | grep -qF 'unmounted /dev/whatever'; then
echo 'your message'
continue
fi
if log | grep -qF 'mounted /dev/whatever'; then
echo 'your other message'
continue
fi
# do you need to echo something in the no match case? might
# be required for dzen, i dunno... if not, you can just remove this
# and the redundant `continue` from the second if statement
echo ' '
done
this could probably be refactored a couple different ways for efficiency (for instance, to read the log file only once, etc) but ill leave it close to your original for now
//github/
Offline
I would go about this a slightly different way. sed seems like a better solution, and there's no need to declare another function to repeatedly call tail on the log.
#!/bin/bash
while read $line; do
sed -n 's,.*\(mounted|unmounted\) /dev/sdd.*,xd card \1,p' <<< "$line"
done < <(inotail -f -n 1 /var/log/everything.log)
I've used inotail instead of tail as its a far better log watcher (uses inotify rather than relying on a buffered output). tail can be safely substituted if you're not interested.
edit: is the while loop even necessary here? With (ino)tail blocking indefinitely while its waiting on data, would something as stupidly simple as 'inotail -f -n 1 /var/log/foo.log | sed ......' be effective?
Last edited by falconindy (2010-07-13 20:46:28)
Offline
I have learned how to shorten functions to one line.
Why do I seem to think I need [ ]'s on my if line's?
I guess grep when finds something returns a "true" so to speak when used in if this way. Much better than counting the words matched like I did. False returned with no match?
Echoing nothing seems like a good idea, as my last message will never disappear.
I had thought of reversing my if's but thought it to be unclean, but maybe the most simple way is the cleanest
Thanks
Last edited by gazj (2010-07-13 18:17:30)
Offline
I would go about this a slightly different way. sed seems like a better solution, and there's no need to declare another function to repeatedly call tail on the log.
#!/bin/bash while read $line; do sed -n 's|.*\(mounted|unmounted\) /dev/sdd.*|xd card \1|p' <<< "$line" done < <(inotail -f -n 1 /var/log/everything.log)
I've used inotail instead of tail as its a far better log watcher (uses inotify rather than relying on a buffered output). tail can be safely substituted if you're not interested.
edit: is the while loop even necessary here? With (ino)tail blocking indefinitely while its waiting on data, would something as stupidly simple as 'inotail -f -n 1 /var/log/foo.log | sed ......' be effective?
I knew a 1 or 2 liner would come along which I totally would struggle to understand. I need to walk before I can run
I do appreciate both your answers though
Offline
I'm not sure if this would be helpfull, but:
usm () {
DRIVE="/dev/sdb1"
if mount | grep -q $DRIVE; then
umount $DRIVE
else
mount -o rw,noauto,async,user,umask=1000 $DRIVE /mnt/usb
fi;
}
I use it to mount my usb drive. Of course you can use
echo 'your other message'
instead of the mount / unmount ones I have.
Offline
Why do I seem to think I need [ ]'s on my if line's?
all you need between the 'if' and the '; then' is an exit status.
'[' is just another command (note that '[[' is a bash built-in that act very similarly); it will just give you that exit status depending how all the stuff before the final ']' evaluates.
knowing this...
I guess grep when finds something returns a "true" so to speak when used in if this way. Much better than counting the words matched like I did. False returned with no match?
grep -q is quiet so it won't show your matches (you only need to know that they were there, not what they were). grep considers no-match a failure case and exits 1 (and 0 on match), so putting that directly in the if is just fine.
armed with this, you can even do simple error handling like this:
if ! wget www.something.com; then
# put any code here that should run in the case of a
# failed download
fi
Last edited by brisbin33 (2010-07-13 20:13:00)
//github/
Offline
Offline
I've used inotail instead of tail as its a far better log watcher (uses inotify rather than relying on a buffered output).
Here[1] it says "As of version 7.5 of coreutils tail --follow uses inotify if available (as inotail does)."
Offline
Pages: 1