Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Run a cron process more than every minute UNIX
Yesterday I had the need to run a cron process more than once a minute -- I wanted to grab a still frame from a web camera every 15 seconds, in order to create a time-lapse movie. The standard cron syntax lets you specify the minute(s) at which a task runs, but you cannot (to my knowledge) specify an interval less than once a minute (using */1).

After much Googling, I finally found the solution, posted in some newsgroup somewhere (sorry, I didn't mark the page): create a simple shell script that repeatedly runs the task, with a sleep command between each call to the job. In my case, my shell script looked like this:
#!/bin/sh
open /path/to/getpic.app
sleep 15
open /path/to/getpic.app
sleep 15
open /path/to/getpic.app
sleep 15
open /path/to/getpic.app
sleep 15
This will run the task four times over the course of a minute (not allowing for processing time). I then created my cron entry to call the above script, with the minute interval set to "every minute" (*/1), and sat back to see what would happen (not for the full twelve hours, of course!). The final result? Not too bad, but not perfect -- I captured a frame about every 25 seconds, instead of every 15. I think I need to reduce the sleep value to allow for the processing time of the getpic.app, so I'll try that later today. As for exactly what it was I was capturing for 12 hours, well, that too is for another day. (It will probably show up on my blog, not here -- though I may write up the 'acquire image' bit as a separate hint, as it was a little tricky.)

In summary, if you need a cron task to run more than once a minute, create a simple shell script using sleep, and have it call your other task the required number of times per minute, then tell cron to run that shell script. I'd love to hear if there are better ways to do this (via cron, launchd, or any other mechanism...).
    •    
  • Currently 2.60 / 5
  You rated: 2 / 5 (5 votes cast)
 
[30,431 views]  

Run a cron process more than every minute | 12 comments | Create New Account
Click here to return to the 'Run a cron process more than every minute' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Run a cron process more than every minute
Authored by: fds on May 16, '07 07:51:22AM
If your script is essentially running continuously all the time anyway, you might as well keep it all in one script without adding it to cron or launchd as well.

#!/bin/sh
while : ; do
    open /path/to/getpic.app
    sleep 15
done


[ Reply to This | # ]
Calculate sleep time
Authored by: googoo on May 16, '07 09:03:56AM
You could also calculate the sleep time using date and a little math.

#!/bin/sh
while : ; do
    open /path/to/getpic.app
    sleepTime=$((`date +%S`%15))
    sleep $sleepTime
done

This would repeat every 15 seconds forever.

-Mark



[ Reply to This | # ]
Calculate sleep time--Correction
Authored by: googoo on May 16, '07 05:14:56PM
OK. I did not check my code. This version will work.

#!/bin/sh
while : ; do
    open /path/to/getpic.app
    sleepTime=$((15-`date +%S`%15))
    sleep $sleepTime
done

-Mark



[ Reply to This | # ]
Run a cron process more than every minute
Authored by: skrawcke on May 16, '07 08:23:56AM
if you wanted to do this for a set period of time like 12 hours you could do.
for X in {1..2880}
do
open /path/to/getpic.app
sleep 15
done

this will run the /path/to/getpic.app 2880 times once every 15 sec.
you could also add a few lines like

/bin/date > /var/log/nameofsomelog
echo "Ran /path/to/getpic.app # $X" > /var/log/nameofsomelog


[ Reply to This | # ]
Run a cron process more than every minute
Authored by: bryanc on May 16, '07 08:51:07AM
If you want to be sure that your job is run every 15 seconds, regardless of the processing time it takes:
while true; do
     /path/to/getpic.app &
     sleep 15
done


[ Reply to This | # ]
Run a cron process more than every minute
Authored by: bryanc on May 16, '07 08:52:33AM

I left out the obvious "open" there.



[ Reply to This | # ]
Applescript?
Authored by: Joraamn on May 16, '07 09:54:10AM
I can't find the source just now, but I did exactly the same thing a few years ago using Applescript. If I recall, it used an idle handler and the 'curl' command. It created a timestamped name for the downloaded images, then I put them together in iMovie. Here is the result after running it for a week.

[ Reply to This | # ]
Run a cron process more than every minute
Authored by: adrianm on May 16, '07 10:51:59AM

launchd will let you run things down to per-second level. If the xml descriptors scare you, download and use Lingon to configure the job.



---
~/.sig: not found



[ Reply to This | # ]
Run a cron process more than every minute
Authored by: viadd on May 16, '07 08:35:08PM
Any solution that just sleeps 15 and then does something, repeatedly, will drift away from once every 15 seconds, due to the non-zero time it takes to do something. And that can vary depending on the load on your computer.

To stay in cadence, you can just sleep however long it takes until the time is evenly divisible by 15 seconds. This takes the limited but non-zero arithmetic available to the bash shell.


#! /usr/bin/env bash
dt=15
for (( i = 0 ; i < 10000 ; i++))
  do
   now=`date +%s`
   left=`expr ${dt} - \( ${now}  % ${dt} \)`
   sleep $left
   open /path/to/getpic.app 
  done


[ Reply to This | # ]
Run a cron process more than every minute
Authored by: frankiec on May 16, '07 10:27:24PM

You rock.



[ Reply to This | # ]
Run a cron process more than every minute
Authored by: bdm on May 17, '07 03:42:57AM

Something like this is the way to go if only shell tools are to be used, but this solution has problems. If the open is fast enough, the time in seconds might be the same multiple of dt that it was before. Then sleep 0 will be executed and the open will be executed too soon. A quick fix would be to test for 0 sleep times and change them to dt. Better would be to monitor the execution starts explicitly. Get the time at the beginning, say "start" and at iteration i sleep until time start+dt*i where the first iteration is i=1.

Brendan.



[ Reply to This | # ]
Run a cron process more than every minute
Authored by: viadd on May 17, '07 09:00:55PM

The expression "${dt} - \( ${now} % ${dt} \)" always gives a value from 1 to 15 (for dt = 15). The '%' operator takes the remainder when now is divided by 15, which is always in the range 0-14 , and 15 minus that puts it in the 15-1 range, respectively.

Thus there won't be any cases of sleep 0, even if open takes 0 seconds.



[ Reply to This | # ]