I just wrote the following snippet to quickly rotate some log files. I know this runs without bound, that's acceptable and desirable in this case. What I'm worried about is creating race conditions if this gets run from cron every minute...
###check if daemon has died### if daemon-is-dead; then L=mydaemon.log shopt -u failglob for i in $( ls -1r ${L}.[0-9]* 2>/dev/null ); do N=${i#$L.} M=$(( ${N} + 1 )) mv -n $i "${L}.${M}" done if [ -f ${L} ] ; then mv -n ${L} ${L}.1; fi restart-daemon fi
Am I shooting myself in the foot here? The obvious race condition is if two copies run simultaneously, but this is only for temporary debugging purposes. If necessary, I'll change the cron job from every minute to every five minutes. Even then, the '-n' option to GNU mv should protect me...? Does anyone have a safer way to do this sort of thing manually? I don't want this logfile managed by logrotate(8).
-Adam Thompson DMTS (Contractor) athompso@dmts.biz (204) 291-7950 - direct (204) 489-6515 - fax
On 12-07-12 07:59 PM, Adam Thompson wrote:
I just wrote the following snippet to quickly rotate some log files. I know this runs without bound, that's acceptable and desirable in this case. What I'm worried about is creating race conditions if this gets run from cron every minute...
###check if daemon has died### if daemon-is-dead; then L=mydaemon.log shopt -u failglob for i in $( ls -1r ${L}.[0-9]* 2>/dev/null ); do N=${i#$L.} M=$(( ${N} + 1 )) mv -n $i "${L}.${M}" done if [ -f ${L} ] ; then mv -n ${L} ${L}.1; fi restart-daemon fi
Am I shooting myself in the foot here? The obvious race condition is if two copies run simultaneously, but this is only for temporary debugging purposes. If necessary, I'll change the cron job from every minute to every five minutes. Even then, the '-n' option to GNU mv should protect me...? Does anyone have a safer way to do this sort of thing manually? I don't want this logfile managed by logrotate(8).
-Adam Thompson DMTS (Contractor) athompso@dmts.biz (204) 291-7950 - direct (204) 489-6515 - fax
_______________________________________________ Roundtable mailing list Roundtable@muug.mb.ca http://www.muug.mb.ca/mailman/listinfo/roundtable
Going to sound like a dumb answer... Why not check the ps list to see if there is more than one instance running. If not then you are good to go. Otherwise shut it down.
Later Mike
I'd use a lock file just to be safe. Depending on how "restart-daemon" works you might end up with a race condition inside there, resulting in no daemon getting run until the next pass.
The easiest way would be
lock="/var/run/mylock" if [ -f $lock ]; then exit 1; else touch $lock; fi #do your magic rm $lock
There are other utilities like flock and lockfile if you are really concerned about re-entrancy, and depending on the user you run this script as, you may want to put $lock out of a normal user's reach. But to protect something running from cron, this will be more than enough.
Sean
On Thu, Jul 12, 2012 at 7:59 PM, Adam Thompson athompso@dmts.biz wrote:
I just wrote the following snippet to quickly rotate some log files. I know this runs without bound, that's acceptable and desirable in this case. What I'm worried about is creating race conditions if this gets run from cron every minute...
###check if daemon has died### if daemon-is-dead; then L=mydaemon.log shopt -u failglob for i in $( ls -1r ${L}.[0-9]* 2>/dev/null ); do N=${i#$L.} M=$(( ${N} + 1 )) mv -n $i "${L}.${M}" done if [ -f ${L} ] ; then mv -n ${L} ${L}.1; fi restart-daemon fi
Am I shooting myself in the foot here? The obvious race condition is if two copies run simultaneously, but this is only for temporary debugging purposes. If necessary, I'll change the cron job from every minute to every five minutes. Even then, the '-n' option to GNU mv should protect me...? Does anyone have a safer way to do this sort of thing manually? I don't want this logfile managed by logrotate(8).
-Adam Thompson DMTS (Contractor) athompso@dmts.biz (204) 291-7950 - direct (204) 489-6515 - fax
Roundtable mailing list Roundtable@muug.mb.ca http://www.muug.mb.ca/mailman/listinfo/roundtable
On 2012-07-12, at 9:04 PM, Sean Walberg wrote:
I'd use a lock file just to be safe. Depending on how "restart-daemon" works you might end up with a race condition inside there, resulting in no daemon getting run until the next pass.
The easiest way would be
lock="/var/run/mylock" if [ -f $lock ]; then exit 1; else touch $lock; fi #do your magic rm $lock
There are other utilities like flock and lockfile if you are really concerned about re-entrancy, and depending on the user you run this script as, you may want to put $lock out of a normal user's reach. But to protect something running from cron, this will be more than enough.
Sean
Sean beat me to it! :)
The only thing I have to add is that (if you are using bash and a recent release) that you trap as many signals as possible (post lock file creation) and in that trap remove the lock file. Otherwise you are in a fun state where everything looks alright but isn't running because the lock didn't get removed for a random number of reasons.
ie.
trap "rm $lock" SIGINT SIGHUP SIGTERM SIGALRM
eg 2. #!/bin/bash LOCKFILE=/var/run/mylock
[ -f $LOCKFILE ] && exit 0 trap "{ rm -f $LOCKFILE ; exit 255; }" SIGINT SIGHUP SIGTERM SIGALRM EXIT touch $LOCKFILE # do your magic here exit 0 # note this will call the trap. :)
Agree about the lock file to prevent race conditions.
I think you'll also run into problems when M reaches 10, because ls -1r won't sort numerically when the number of digits varies. You'd need to either stick to to single digits for the version number, or pipe the ls output to "sort -t. -k 3nr" to get a proper reverse numeric sort. Otherwise the rotation order will get really messed up.
On 12/07/2012 9:04 PM, Sean Walberg wrote:
I'd use a lock file just to be safe. Depending on how "restart-daemon" works you might end up with a race condition inside there, resulting in no daemon getting run until the next pass.
The easiest way would be
lock="/var/run/mylock" if [ -f $lock ]; then exit 1; else touch $lock; fi #do your magic rm $lock
There are other utilities like flock and lockfile if you are really concerned about re-entrancy, and depending on the user you run this script as, you may want to put $lock out of a normal user's reach. But to protect something running from cron, this will be more than enough.
Sean
On Thu, Jul 12, 2012 at 7:59 PM, Adam Thompson <athompso@dmts.biz mailto:athompso@dmts.biz> wrote:
I just wrote the following snippet to quickly rotate some log files. I know this runs without bound, that's acceptable and desirable in this case. What I'm worried about is creating race conditions if this gets run from cron every minute... ###check if daemon has died### if daemon-is-dead; then L=mydaemon.log shopt -u failglob for i in $( ls -1r ${L}.[0-9]* 2>/dev/null ); do N=${i#$L.} M=$(( ${N} + 1 )) mv -n $i "${L}.${M}" done if [ -f ${L} ] ; then mv -n ${L} ${L}.1; fi restart-daemon fi Am I shooting myself in the foot here? The obvious race condition is if two copies run simultaneously, but this is only for temporary debugging purposes. If necessary, I'll change the cron job from every minute to every five minutes. Even then, the '-n' option to GNU mv should protect me...? Does anyone have a safer way to do this sort of thing manually? I don't want this logfile managed by logrotate(8). -Adam Thompson DMTS (Contractor) athompso@dmts.biz <mailto:athompso@dmts.biz> (204) 291-7950 <tel:%28204%29%20291-7950> - direct (204) 489-6515 <tel:%28204%29%20489-6515> - fax _______________________________________________ Roundtable mailing list Roundtable@muug.mb.ca <mailto:Roundtable@muug.mb.ca> http://www.muug.mb.ca/mailman/listinfo/roundtable
-- Sean Walberg <sean@ertw.com mailto:sean@ertw.com> http://ertw.com/
Roundtable mailing list Roundtable@muug.mb.ca http://www.muug.mb.ca/mailman/listinfo/roundtable
I nominate this as the geekiest thread on MUUG in recent memory.
Nicely done boys! Reminds me why i'm on this list.
Oh ya, and what Sean(s) said. Lockfile.
John