[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: if the file changes send email about diff



kellyremo wrote:
> I have 2 script. Script "A", Script "B".
> 
> Script "A" is regulary watching the "dhcpacks" [dhcp release is
> configured to 2mins] in the logs, for the past 2 minutes. it writes
> the MAC addresses to a file [/dev/shm/dhcpacks-in-last-2min.txt]
> every 2 minutes. Ok, this is working, active clients are in this
> file. Super!
> 
> Script "B": http://pastebin.com/raw.php?i=wvhwhPWu I'm trying to
> create a script, that watches the changes in
> "/dev/shm/dhcpacks-in-last-2min.txt" file [in every 1 sec]. Ok. But:
> my "watcher" script [the pastebined] is not working fine...sometime
> it works, sometime it send that someone "XY logged out", but it's
> not true! nothing happened, and the problem is not in the Script
> "A".
> 
> Can someone help me point out, what am i missing?

I looked at your pastebin script and have several comments.

* The indentation is terrible!  Please indent according to control and
  not just randomly.

* Your use of named temporary files isn't secure.  But I assume it
  isn't a problem so will just note it.

* Avoid discarding error output.  You have:

    grep PATTERN > /dev/null 2>&1

  Instead of doing that use grep -q.  Otherwise you throw away useful
  error messages.

    grep -q PATTERN

Most importantly the way you are getting the differences doesn't make
any sense to me.

  while true; do
    DHCPACKSBEF=$(cat /dev/shm/dhcpacks-in-last-2min.txt)
    sleep 1
    DHCPACKSAFT=$(cat /dev/shm/dhcpacks-in-last-2min.txt)
    ...
  done

What!?  This is why it is only randomly working for you.  It only
catches an update if it is lucky enough that the file is updated
during the one second of sleep time.  But if it ever updates outside
of that window, which is also very likely, then you will miss it.

This is your problem.  Start there and rewrite it so that it avoids
that problem.

> How can i watch a file [in every sec], that contains only MAC
> addresses, and if someone doesn't get dhcpack in 2 minutes, the file
> "/dev/shm/dhcpacks-in-last-2min.txt" changes, and that clients MAC
> address will be gone from it, and i need to know, who was it

How would I do it?  I don't know.  I haven't thought about it.  There
are probably ten ways to do it.  On first glance I would probably keep
a full snapshot of the file and then see if it is different.  Of
course since the upstream file can change at any time you can't look
at it more than once.  You must grab a copy exactly once and then work
with the working copy.  Here is something off the top of my head.
Note that I haven't tested it or even run it but just typed something
into the email.

test -f /tmp/last-dhcpd-acks && cp /tmp/dhcpacks-in-last-2min.txt /tmp/last-dhcpd-acks
while sleep 1; do
  cp /tmp/dhcpacks-in-last-2min.txt /tmp/dhcp-acks-wc # snapshot a working copy
  if ! cmp -s /tmp/dhcp-acks-wc /tmp/last-dhcpdacks; then
    # The files are different.  Process the differences.
    cp /tmp/dhcpacks-in-last-2min.txt /tmp/last-dhcpd-acks
  fi
done

Look at your script A that creates the upstream file.  How does it
update the file?  Does it do it atomically?  If so then fine.  But if
not then even the above could fail.  The cp could get only part of the
file.  Therefore you need to review your script A too to make sure
that it does an atomic update.  It should write a copy of the file to
the side into a temporary filename and then rename it in the same
directory to the final name.  In the kernel rename(2) is atomic.  This
causes the file to either always be the previous file or the new file
and never anything between.  This is a standard Unix update method.
(That has been called into controversy due to recent mob insanity.)
Doing an atomic update of the file is critically important for
reliable operation.

Good luck!

Bob

Attachment: signature.asc
Description: Digital signature


Reply to: