Вот мой рецепт (протестировал его на двух ноутбуках Ubuntu 16.04):
Поместите этот скрипт где угодно (я положил его в root, /syspend.sh) и сделал его исполняемым (chmod +x /suspend.sh)
TIMELOG=/tmp/autohibernate.log
ALARM=$(tail -n 1 $TIMELOG)
SLEEPTIME=5000 #edit this line to change timer, e.g. 2 hours "$((2*60*60))"
if [[ $1 == "resume" ]]
then
if [[ $(date +%s) -ge $(( $ALARM + $SLEEPTIME )) ]]
then
echo "hibernate triggered $(date +%H:%M:%S)">>$TIMELOG
systemctl hibernate 2>> $TIMELOG
else
echo "normal wakeup $(date +%H:%M:%S)">>$TIMELOG
fi
elif [[ $1 == "suspend" ]]
then
echo "$(date +%s)" >> $TIMELOG
rtcwake -m no -s $SLEEPTIME
fi
Затем создайте цель systemd: # touch /etc/systemd/system/suspend-to-sleep.target Вставьте это содержимое:
#/etc/systemd/system/suspend-to-hibernate.service
[Unit]
Description=Delayed hibernation trigger
Before=suspend.target
Conflicts=hibernate.target hybrid-suspend.target
StopWhenUnneeded=true
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash /suspend.sh suspend
ExecStop=/bin/bash /suspend.sh wakeup
[Install]
WantedBy=sleep.target
RequiredBy=suspend.target
Затем включите его # systemctl enable suspend-to-sleep.target.
Я столкнулся проблема на одном из ноутбуков: закрывающая крышка не запускала эту цель. Это было связано с xfce4-power-manager. Существует два способа решения этой проблемы. Первый - отредактировать файл /etc/systemd/logind.conf и заменить HandleLidSwitch=ignore на HandleLidSwitch=suspend. Но это будет системно, поэтому я просто добавил символическую ссылку на мой скрипт # ln -s /suspend.sh /etc/pm/sleep.d/0000rtchibernate
Я перенаправлял весь вывод в файл с помощью > my.log &, а затем с помощью tail -f my.log просматривал все сообщения. По какой-то причине все e.printstacktrace не были в my.log. Мне не хватало RuntimeException, а точный корень вызывал ArrayOutofboundException.