84

I have a script that needs to be run every five seconds. I know that cron can do tasks by the minute, but is there a way to run something every second?

5
  • 3
    What problem are you trying to solve? Are you sure cron is the right solution?
    – andol
    Commented Aug 4, 2010 at 19:11
  • 1
    I know cron isn't the right solution. I was saying it wasn't in the question. Please read. I am trying to make a script run every 5 seconds.
    – myusuf3
    Commented Aug 4, 2010 at 19:20
  • 2
    Sorry, guess I got the question slightly wrong. Yet, still wondering if you are trying to solve the right problem.
    – andol
    Commented Aug 4, 2010 at 19:25
  • For people coming here looking how to run something every 5 seconds. I strongly recommend instead you look at learning how to program realtime with tools like socket.io as an example. Commented Jul 18, 2017 at 19:05
  • Have you discovered the bash sleep command? sleep 5 pauses (perhaps within a loop) for 5 seconds)...?
    – SDsolar
    Commented Apr 23, 2018 at 19:03

8 Answers 8

76

Cron only allows for a minimum of one minute. What you could do is write a shell script with an infinite loop that runs your task, and then sleeps for 5 seconds. That way your task would be run more or less every 5 seconds, depending on how long the task itself takes.

#!/bin/bash

while true; do
  # Do something
  sleep 5;
done

You can create a my-task.sh file with the contents above and run it with sh my-task.sh. Optionally you can configure it with supervisor as a service so that it would start when the system boots, etc.

It really does sound like you're doing something that you probably shouldn't be doing though. This feels wrong.

2
  • One can need a a cron running every 5 or even less seconds to be used in PHP based scrapers. Commented Dec 26, 2017 at 11:57
  • 1
    Really feels wrong. If you include it in a cron job then you will have overlapping jobs every minute. After an hour 60 jobs will be starting every 5 seconds. If you do not include in a cron job, well, you may not be able to know how to stop it, or even to know it exists.
    – SeF
    Commented Mar 4, 2019 at 14:18
50

You could have a cron job kick-off a script every minute that starts 12 backgrounded processes thusly:

* * * * * ~/dostuff.sh

dostuff.sh:

(sleep 5 && /path/to/task) &
(sleep 10 && /path/to/task) &
(sleep 15 && /path/to/task) &
(sleep 20 && /path/to/task) &
(sleep 25 && /path/to/task) &
(sleep 30 && /path/to/task) &
(sleep 35 && /path/to/task) &
(sleep 40 && /path/to/task) &
(sleep 45 && /path/to/task) &
(sleep 50 && /path/to/task) &
(sleep 55 && /path/to/task) &
(sleep 60 && /path/to/task) &

My question, though, is What on EARTH could you be doing that needs to run every 5 seconds?

8
  • 1
    Well, this came in handy to me when I made a script that repeatedly checks the /media directory for a drive I plug in to usb for automatic backups...
    – VF1
    Commented Aug 22, 2013 at 2:52
  • 60
    What on EARTH - statistics, garbage collection, file sync, online status, you name it.
    – ruX
    Commented Jul 16, 2016 at 23:53
  • 9
    Referencing external API for near-realtime data. Running request every 5 sec is MUCH better than doing it on every pageview. Commented Jul 18, 2016 at 21:41
  • 1
    What if crontab execute the dostuff.sh file twice? For example at 55th second, the script is executed but didn't finished yet, but the cron calls the script again, what'll happen?
    – TomSawyer
    Commented Sep 14, 2016 at 9:16
  • 3
    THIS IS BAD! It potentially runs the script more than once at a time (if it happens to take longer than 5 seconds) which could lead to a race condition in any (even temporary) files accessed. DO NOT DO THIS if doing the same thing twice at the same time could cause a problem! (And that usually will!) Commented Jan 10, 2018 at 1:52
29

Just use a loop:

while true ; do ./your-script & sleep 5; done

This will start your-script as a background job, sleep for 5 seconds, then loop again. You can use Ctrl-C to abort it, or use any other condition instead of true, e.g. ! test -f /tmp/stop-my-script to only loop while the file /tmp/stop-my-script does not exist.

3
  • If I include the ampersand, it says bash: syntax error near unexpected token ';', so I took it out. I have bash 4.3.11. My command runs quickly so it's ok if it runs in the foreground. Commented Dec 4, 2016 at 4:48
  • 1
    @TylerCollier If you did need ./your-script to run in the background (during the 5-second sleep), you could keep & but drop the ;. As & serves the purpose of separating the commands, it's unnecessary (and apparently not allowed) to have ; after it on the same line. Another way is to write the loop in multiple lines (with a line break after & and, optionally, line breaks after do and before done as well). Since the ; after & appears to be a typo, I've removed it. blueyed: Please feel free to put the ; back if you really want it; if so, I suggest also adding an explanation. Commented Dec 30, 2016 at 20:40
  • @EliahKagan FWIW, it works on Zsh (no syntax error), but it is not really necessary. Thanks for the edit!
    – blueyed
    Commented Jan 12, 2017 at 11:43
12

You could use the GNU package mcron, a "Vixie cron" alternative.

http://www.gnu.org/software/mcron/manual/mcron.html#Top

"Can easily allow for finer time-points to be specified, i.e. seconds. In principle this could be extended to microseconds, but this is not implemented."

5
7

You could use a SystemD timer unit, which will trigger a service - that you'd set up to do what you want - every 5 seconds.

Suppose your service unit is called mystuff.service and is installed in /etc/systemd/system (check out SystemD user services if you want to replace a user's crontab), then you can write a timer unit to run the service at boot time and then every 5 seconds, like this:

/etc/systemd/system/mystuff.timer

[Unit]
Description=my stuff's schedule
[Timer]
OnBootSec=5
OnUnitActiveSec=5
[Install]
WantedBy=timers.target

Then reload the systemd configuration, enable the timer unit and start it.

5
  • 2
    It's the best solution, the only downside is that cron is a lot easier to overview and configure. SystemD is a pain and it starts with it's directory structure. Still the best for a 5 second interval
    – John
    Commented Dec 17, 2018 at 17:32
  • Wouldn't the above snippet go in /etc/systemd/system/mystuff.timer instead of mystuff.service?
    – Brooks
    Commented Jan 17, 2019 at 14:05
  • @Brooks: yes, my bad - bad copy & paste on my side. Fixed.
    – Guss
    Commented Jan 17, 2019 at 14:13
  • Thanks...glad to know I'm not crazy while I'm learning systemd :)
    – Brooks
    Commented Jan 17, 2019 at 14:13
  • I love this approach
    – saviour123
    Commented Jul 22, 2020 at 17:01
2

Minimum configuration in cron is minutes, you can't set it for 5 seconds. You could use Quartz which does allow seconds. http://www.quartz-scheduler.org/docs/tutorials/crontrigger.html

3
  • It seems Quartz is not open source. Is this correct?
    – txwikinger
    Commented Aug 4, 2010 at 19:24
  • It has an open source version. It doesn't have a page but just go to the download page. You don't have to fill out the form just click take me to the download. Commented Aug 4, 2010 at 19:27
  • seems to be open source as of at least 2018. github.com/quartz-scheduler/quartz
    – dogmatic69
    Commented Feb 18, 2018 at 16:39
2

Use cacti to monitor router and switch,but Cron only allows for a minimum of one minute,so if one port/device down,there is no warning until two minutes past.

1
  • 1
    I recommend editing this answer to expand it with specific details about how to do this. (See also How do I write a good answer? for general advice about what sorts of answers are considered most valuable on Ask Ubuntu.) Commented Feb 23, 2016 at 8:51
1

I've done this sort of thing very successfully (and the end result rans weeks at a time, till the machine is rebooted). As for what I was doing right now, updating information and putting it into cache - updating every 10 seconds.

#!/bin/sh

SLEEP=5

# do stuff
sleep $SLEEP

# do stuff
sleep $SLEEP

# do stuff
sleep $SLEEP

# do stuff
sleep $SLEEP

# echo and restart...
exec $0

The 'exec $0' restarts the script, but replacing the running script. It can be initially started with a crontab '@reboot' line.

1
  • 10
    Why not use a while loop instead of repeatedly restarting the script?
    – David Z
    Commented Aug 4, 2010 at 19:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .