yun's attic

Waking Up with rtcwake and crontab

I have a couple of scripts that I’d like to run at night, but I also want to leave my machine suspended to RAM overnight to conserve energy (and reduce noise, the fan is a beast!). So this is just a note for myself about how I went about it this time, using rtcwake and crontab.

Here’s the crontab I originally had, which is triggered once a day in the afternoon:

59 15 * * *  /some/bash/script.sh

But now I want to run it at night, when I’m not around my computer, which like me is probably also asleep. So I need to make sure the machine is in an awake state just before the cron jobs are scheduled to be executed.

Some minutes of DuckDuckGo later I found rtcwake, which uses the hardware clock on the motherboard to send a signal to wake up the machine at desired time. Sounds like exactly what I need.

So now my crontab becomes:

1  4 * * *  sudo rtcwake -m no -t $(date +\%s -d "tomorrow 03:55")
59 3 * * * /some/bash/script.sh

Some explanations:

  • rtcwake needs root permission, hence the sudo.
  • The -m no flag only sets an alert to wake up the machine. If the machine is already awake, nothing will change.
  • The main idea is to start a cycle: rtcwake wakes up the machine (03:55) a few minutes before the scheduled cron job (03:59), and then another cron job (04:01) uses rtcwake to set up the next alert for tomorrow.
  • After everything is done, the machine will go to sleep after 30 minutes according to some other energy saving settings I have.

I waited for one night, but it did not work as I expected (it’s the first-time-never-works-law).

Because rtcwake requires root permission, it needs the root password when that cron job is run. But given it’s a bad idea to store root passwords anywhere it’s better to use root’s crontab instead of the one owned by the user. In other words, it would be two separate crontabs:

  • with sudo crontab -e:

    1  4 * * *  sudo rtcwake -m no -t $(date +\%s -d "tomorrow 03:55")
    
  • with your regular crontab -e (of course, this can also be run under root’s crontab, but I don’t want to clutter that up):

    59 3 * * * /some/bash/script.sh
    

Et voilà, it’s as sweet as a dream, pun intended.

The only issue is if your machine restarts during the day and failed to run the crontab containing rtcwake, you’ll have to do it manually once to get the cycle started.

Menu