tags:

views:

185

answers:

5

I have this Perl script for monitoring a folder in Linux.

To continuously check for any updates to the directory, I have a while loop that sleeps for 5 minutes in-between successive loops :

while(1) {

    ...
    sleep 300;
}

Nobody on my other question suggested using cron for scheduling instead of a for loop.

This while construct, without any break looks ugly to me as compared to submitting a cronjob using crontab :

0 */5 * * * ./myscript > /dev/null 2>&1
  • Is cron the right choice? Are there any advantages of using the while loop construct?
  • Are there any better ways of doing this except the loop and cron?

Also, I'm using a 2.6.9 kernel build.

+5  A: 

The only reasons I have ever used the while solution is if either I needed my code to be run more than once a minute or if it needed to respond immediately to an external event, neither of which appear to be the case here.

My thinking is usually along the lines of: cron has been tested by millions and millions of people over decades so it's at least as reliable as the code I've just strung together.

Even in situations where I've used while, I've still had a cron job to restart my script in case of failure.

My advice would be to simply use cron. That's what it's designed for. And, as an aside, I rarely redirect the output to /dev/null, that makes it too hard to debug. Usually I simply redirect to a file in the /tmp file system so that I can see what's going on.

You can append as long as you have an automated clean-up procedure and you can even write to a more private location if you're worried about anyone seeing stuff in the output.

The bottom line, though, is that a rare failure can't be analysed if you're throwing away the output. If you consider your job to be bug-free then, by all means, throw the output away but I rarely consider my scripts bug-free, just in case.

paxdiablo
+1 for the 'do not throw away the errors your program tries to report' part.
Jonathan Leffler
You can get cron to run a job faster than once a second by introducing a delay before the script runs. For instance, to get `foo.sh` to run four times a second you can say: `* * * * * foo.sh`, `* * * * * sleep .25; foo.sh`, `* * * * * sleep .5; foo.sh`, and `* * * * * sleep .75; foo.sh`.
Chas. Owens
@Chas. Owens - cron has a resolution of once per minute, not second. But of course your solution with sleep still works for that.
Sec
You can also dump the output of your job to logger(1), which will dump it into whatever syslog file you have configured, and those logs will be maintained by whatever log rotator your system uses. Try `yourscriptname | logger -t yourscriptname`.
Blrfl
The `while()` approach can also be useful when the processing is long-running, and you don't want to run the risk of concurrent invocations of the script causing chaos. This is something that you have to at least consider with `cron`. There are also some circumstances where it can be beneficial to have the script `at` itself for some time in the future rather than sleeping.
RET
+4  A: 
  1. Why don't you make the build process that puts the build into the directory do the notification? (See SO 3691739 for where that comes from!)

  2. Having cron run the program is perfectly acceptable - and simpler than a permanent loop with a sleep, though not by much.

  3. Against a cron solution, since the process is a simple one-shot, you can't tell what has changed since the last time it was run - there is no state. (Or, more accurately, if you provide state - via a file, probably - you are making life much more complex than running a single script that keeps its state internally.)

  4. Also, stopping the notification service is less obvious. If there's a single process hanging around, you kill it and the notifications stop. If the notifications are run by cron, then you have to know that they're run out of a crontab, know whose crontab it is, and edit that entry in order to stop it.

  5. You should also consider persuading your company to upgrade to a version of Linux where the inotify mechanism is available.

Jonathan Leffler
@Jonathan: 1) the build process is handled separately, almost out of my control. 3) actually there is a state in the sense that the "cache" file stores the timestamp of the last time there was a change.
Lazer
thanks for mentioning that I can't use a state within a program when using `cron`.
Lazer
+1  A: 

If you go for the loop instead of cron and want your job run at regular intervals, sleep(300) tends to drift. (consider the execution time of the rest of your script)

I suggest using a construct like this:

use constant DELAY => 300;

my $next=time();
while (1){
    $next+=DELAY;

    ...;

    sleep ($next-time());
};
Sec
A: 

Yet another alternative is the 'anacron' utility.

David Cary
A: 

if you don't want to use cron. this http://upstart.ubuntu.com/ can be used to babysit processes. or you can use watch whichever is easier.

bronzebeard