I’ve been meaning to look into this for a while. My Ubuntu server acts as a NAS drive. As such it’s on all the time, but really it needn’t be. So let’s look at what we can do to save some energy by “hibernating” late in the evening and restarting early in the morning…
Let’s start with the /usr/sbin/rtcwake command. This application will tell your Linux OS to go into a sleep/hibernate state and you supply it with a time to wake back up, for example
/usr/sbin/rtcwake -m off
The -m switch specifies the type of suspend. Options include
- standby this option is the least energy efficient option and is the default option if you do not set the -m switch, it’s also very fast at resuming a system from sleep.
- mem this option suspends to RAM, this puts everything into a low powered state (except RAM) and offers significant savings in energy.
- disk this option suspends disk operations, the contents of memory are written to disk then restored when the computer wakes up.
- off this option turns the computer off completely
- no this option allows you to specify the awake time but doesn’t suspect the computer. The idea is that the user would put the machine into hibernation
and rtcwake would then wake it up again at the specified point in time.
We might wish to set the resume time using either seconds (i.e. how many seconds in the future does the system resume) using the -s options, for example to wake up 10 hours after going to sleep we would specify 36000 seconds, like this
/usr/sbin/rtcwake -m off -s 36000
or to specify a time we use the -t switch which requires the number of seconds since Unix epoch (i.e. Jan 1st 1970, 00:00:00) so we still need to calculate to seconds
/usr/sbin/rtcwake -m off -t $(date +%s -d ‘tomorrow 07:00’)
If your hardware clock is set to local time, you’ll want to use the -l switch, for example
/usr/sbin/rtcwake -m off -l -t $(date +%s -d ‘tomorrow 07:00’)
Below is a script taken from StackOverflow. Just save this script as wakeup.sh or whatever file name and chmod to executable.
#!/bin/sh # unix time in s that we should wake at waketime=$(date +%s -d '07:00') # make sure the time we got is in the future if [ $(date +%s) -gt $waketime ]; then # if not add a day 60s * 60s * 24h waketime=$(($waketime + 86400)) fi # time in S from now till then dif=$(($waketime - $(date +%s))) # tell the user echo echo "Current Time : $(date +%s)" echo "Wake Time : $waketime" echo "Seconds From Now : $dif" echo echo "Ctrl-C to Cancel in 5s" echo sleep 5 # sleep with rtcwake /usr/sbin/rtcwake -m off -l -s $dif echo "Shutdown."#!/bin/sh
But wait, we can run this rtcwake command (or the above script) manually but for my scenario I’d really want want it run automatically. So we add a cronjob as sudo (as rtcwake will need to be run as sudo) i.e.
sudo crontab -e
Now add the following
0 0 * * * /home/putridparrot/wakeup.sh > /home/putridparrot/wakeup.log
As per crontab expectations the arguments are as follows
- MIN: Minute 0-60
- HOUR: Hour, 24 hour clock hence 0-23
- MDAY: Day of the Month, 1-31
- MON: Month, 1-12 or jan, feb…dec
- DOW: Day of the week, 0-6 or sun, mon, tue…sat
- COMMAND: The command to run
So with this knowledge, our script will run at 12:00am every day. I found it useful to create a log of the output of the script, just to ensure I could see it had run. Remember > will create a new file overwriting any existing file or you could use >> to append to an existing file if you prefer (but then you might want a cronjob to delete the file periodically).
You can also check the syslog for CRON jobs via
grep CRON /var/log/syslog