2

I have in my crontab the following

15 */4 * * * ...

My original intent was that I would run ... every 4 hours from when the computer boots up. If I power on at 8 am, it would run at 8, 12, 16, 20, ...; if I power on at 9am it would run at 9, 13, 17, 21, ...

My observation is that crontab seems to divide the hour by 4 and if the remainder is 0 it executes.

Is there a way I can achieve the former rather than the latter?

chribonn
  • 311

3 Answers3

6

This is something that might more easily be done on current Ubuntu systems using a systemd timer.

Following the monotonic timer example in the archlinux wiki:

  1. create a service unit file to run your command (/usr/local/bin/foo in this example) as a oneshot service

    [Unit]
    Description=do some stuff on schedule defined by foo.timer
    

    [Service] Type=oneshot ExecStart=/usr/local/bin/foo

  2. create a corresponding timer unit with the desired time specifications (0 seconds after boot, and then 4 hours after the service unit was last activated)

    [Unit]
    Description=Run foo on boot and every 4 hours thereafter
    

    [Timer] OnBootSec=0 OnUnitActiveSec=4h

    [Install] WantedBy=timers.target

  3. enable the timer

    sudo systemctl enable foo.timer
    

After reboot, you should be able to see the new timer along with its last and next activation times:

$ systemctl list-timers foo
NEXT                        LEFT          LAST                        PASSED      UNIT      ACTIVATES  
Thu 2023-01-12 19:37:39 EST 3h 58min left Thu 2023-01-12 15:37:39 EST 1min 5s ago foo.timer foo.service

1 timers listed. Pass --all to see loaded but inactive timers, too.

steeldriver
  • 142,475
3

The number after / is called a step value and it starts counting from hour 00 to hour 23 for hours ... So:

15 */4 * * *   ...

translates to at minute 15 past every 4th hour starting from hour 00 ... not from reboot.

You might want:

@reboot sleep 4h ...

That is wait for 4 hours after the system starts then run the command ... That, however, will run the command only once after each reboot ... To continue running the command every 4 hours after each reboot until shutdown, then you can add your command/s to a script file like so:

#!/bin/bash

while true; do

command/s here will first run immediately after boot

sleep 4h

command/s here will first run 4 hours after boot

done

then use that script file in the crontab line like so:

@reboot /bin/bash /full/path/to/scriptfile
Raffa
  • 34,963
0

Have you considered the use of at as a scheduler?

At boot time, run a script that schedules an 'at' job four hours hence and passes the time it ran to something the at job can read (e.g. a file somewhere, e.g. within the at job itself, e.g. a parameter passed to the 'at' job, there are many ways you can pass the parameter).

When the 'at' job runs, at some point in the script run it schedules another 'at' job exactly 4 hours after it was launched. This will only suffer schedule creep or not-four-hourness at times your system clock enters or exist DST (twice a year if the timezone it runs in uses daylight saving) or when the system clock gets a time adjustment...

houninym
  • 101