В любом KDE 4 + есть приложение под названием «Системные настройки».
Вы найдете раздел «Ярлыки и жесты». Вы найдете все возможные действия и сможете назначить любую клавиатуру любому жесту и даже создать свои собственные.
Не бойтесь его, он очень прост в использовании, и вы можете установить " основные ярлыки "и" альтернативные ярлыки ", поэтому вам даже не нужно удалять оригинал:)
Еще одно распространенное обходное решение, которое вы можете использовать hybrid-sleep (например, Mac OS). Если ваш компьютер поддерживает спящий режим, вы можете использовать эту функцию:
systemctl hybrid-sleep
Эта команда должна приостанавливать и отправлять на диск (спящий режим) компьютер. Через некоторое время компьютер выключится (при включении он будет использовать файлы гибернации для пробуждения).
ps: Я знаю, что это не совсем то, что выложили OP, но это довольно близко
Вот мой рецепт (протестировал его на двух ноутбуках 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
Вас может заинтересовать s2both . Он предоставляется пакетом uswsusp
в Ubuntu 10.10. Он приостанавливается на диск, но вместо выключения система вместо этого помещает его в S3, который является режимом питания, обычно связанным с опцией «Приостановить» в Ubuntu. pm-suspend-hybrid - еще один инструмент, который пытается сделать то же самое.
Чтобы автоматизировать работу с крышкой, ознакомьтесь со следующим руководством, которое позволяет вам запускать произвольный скрипт при захвате события крышки:
http://ubuntuforums.org/showthread.php?t=1076486
Если вы случайно есть ThinkPad, manpage для tpctl
ссылается на аргумент, - pm-sedation-hibernate-from-suspend-timer
, который, кажется, обеспечивает функцию, ищу. Я бы предостерег вас от попытки использовать это на оборудовании, отличном от ThinkPad.
Для справки я просмотрел справочную страницу для hibernate.conf ; у него, казалось, не было каких-либо подходящих вариантов, но, возможно, стоило бы второго чтения.
Не забудьте chmod + x этот файл, сделайте его исполняемым.
Есть еще одно решение без rtcwake, используя wakealarm в / sys / class / rtc / rtc0. Использовать устаревший код в pm-functions (/ usr / lib / pm-utils) после комментариев #, поскольку ядро не поддерживает напрямую ..., (потому что текущее ядро (после чего-то 3.6) напрямую поддерживает). Верните этот код и добавьте в do_suspend () вместо do_suspend_hybrid ().
Устаревший код (приостановить, затем спящий режим, когда вызывается suspend_hybrid):
# since the kernel does not directly support hybrid sleep, we do
# something else -- suspend and schedule an alarm to go into
# hibernate if we have slept long enough.
# Only do this if we do not need to do any special video hackery on resume
# from hibernate, though.
if [ -z "$SUSPEND_HYBRID_MODULE" -a -w "$PM_RTC/wakealarm" ] && \
check_suspend && check_hibernate && ! is_set $HIBERNATE_RESUME_POST_VIDEO; \
then
SUSPEND_HYBRID_MODULE="kernel"
do_suspend_hybrid() {
WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
echo >"$PM_RTC/wakealarm"
echo $WAKETIME > "$PM_RTC/wakealarm"
if do_suspend; then
NOW=$(cat "$PM_RTC/since_epoch")
if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ]; then
log "Woken by RTC alarm, hibernating."
# if hibernate fails for any reason, go back to suspend.
do_hibernate || do_suspend
else
echo > "$PM_RTC/wakealarm"
fi
else
# if we cannot suspend, just try to hibernate.
do_hibernate
fi
}
fi
Рекомендуется. Еще проще использовать uswsusp в то же время максимизировать выгоду s2both, т. Е. S2both при приостановке. Поместите восстановленный код в do_suspend () часть модуля uswsusp (/usr/lib/pm-utils/module.d).
Возвращенный код (suspend_hybrid при вызове suspend):
WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
echo >"$PM_RTC/wakealarm"
echo $WAKETIME > "$PM_RTC/wakealarm"
if do_suspend_hybrid; then
NOW=$(cat "$PM_RTC/since_epoch")
if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ]; then
log "Woken by RTC alarm, hibernating."
# if hibernate fails for any reason, go back to suspend_hybrid.
do_hibernate || do_suspend_hybrid
else
echo > "$PM_RTC/wakealarm"
fi
else
# when do_suspend is being called, convert to suspend_hybrid.
do_suspend_hybrid
fi
С помощью uswsusp мы можем видеть прогресс suspend / hibernate и обратный процесс, отображаемый в тексте, даже мы можем прервите его, нажав обратное пространство. Без uswsusp, suspend / hibernate просто появляются - исчезают досадно, особенно когда запускается wakealarm и выполняется спящий режим (s2disk в uswsusp). Установите период сна перед спящим в обычном месте в файле pm-functions.
# variables to handle hibernate after suspend support
PM_HIBERNATE_DELAY=900 # 15 minutes
PM_RTC=/sys/class/rtc/rtc0
Вот мода uswsusp: (помните, этот модуль вызывается из pm-функций, поэтому вставленные переменные одинаковы )
#!/bin/sh
# disable processing of 90chvt and 99video.
# s2ram and s2disk handle all this stuff internally.
uswsusp_hooks()
{
disablehook 99video "disabled by uswsusp"
}
# Since we disabled 99video, we need to take responsibility for proper
# quirk handling. s2ram handles all common video quirks internally,
# so all we have to do is translate the HAL standard options to s2ram options.
uswsusp_get_quirks()
{
OPTS=""
ACPI_SLEEP=0
for opt in $PM_CMDLINE; do
case "${opt##--quirk-}" in # just quirks, please
dpms-on) ;; # no-op
dpms-suspend) ;; # no-op
radeon-off) OPTS="$OPTS --radeontool" ;;
reset-brightness) ;; # no-op
s3-bios) ACPI_SLEEP=$(($ACPI_SLEEP + 1)) ;;
s3-mode) ACPI_SLEEP=$(($ACPI_SLEEP + 2)) ;;
vbe-post) OPTS="$OPTS --vbe_post" ;;
vbemode-restore) OPTS="$OPTS --vbe_mode" ;;
vbestate-restore) OPTS="$OPTS --vbe_save" ;;
vga-mode-3) ;; # no-op
save-pci) OPTS="$OPTS --pci_save" ;;
none) QUIRK_NONE="true" ;;
*) continue ;;
esac
done
[ $ACPI_SLEEP -ne 0 ] && OPTS="$OPTS --acpi_sleep $ACPI_SLEEP"
# if we were told to ignore quirks, do so.
# This is arguably not the best way to do things, but...
[ "$QUIRK_NONE" = "true" ] && OPTS=""
}
# Since we disabled 99video, we also need to handle displaying
# help info for the quirks we handle.
uswsusp_help()
{
echo # first echo makes it look nicer.
echo "s2ram video quirk handler options:"
echo
echo " --quirk-radeon-off"
echo " --quirk-s3-bios"
echo " --quirk-s3-mode"
echo " --quirk-vbe-post"
echo " --quirk-vbemode-restore"
echo " --quirk-vbestate-restore"
echo " --quirk-save-pci"
echo " --quirk-none"
}
# This idiom is used for all sleep methods. Only declare the actual
# do_ method if:
# 1: some other sleep module has not already done so, and
# 2: this sleep method can actually work on this system.
#
# For suspend, if SUSPEND_MODULE is set then something else has already
# implemented do_suspend. We could just check to see of do_suspend was
# already declared using command_exists, but using a dedicated environment
# variable makes it easier to debug when we have to know what sleep module
# ended up claiming ownership of a given sleep method.
if [ -z "$SUSPEND_MODULE" ] && command_exists s2ram && \
( grep -q mem /sys/power/state || \
( [ -c /dev/pmu ] && check_suspend_pmu; ); ); then
SUSPEND_MODULE="uswsusp"
do_suspend()
{
WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
echo >"$PM_RTC/wakealarm"
echo $WAKETIME > "$PM_RTC/wakealarm"
if do_suspend_hybrid; then
NOW=$(cat "$PM_RTC/since_epoch")
if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ]; then
log "Woken by RTC alarm, hibernating."
# if hibernate fails for any reason, go back to suspend_hybrid.
do_hibernate || do_suspend_hybrid
else
echo > "$PM_RTC/wakealarm"
fi
else
# when do_suspend is being called, convert to suspend_hybrid.
do_suspend_hybrid
fi
}
fi
if [ -z "$HIBERNATE_MODULE" ] && \
[ -f /sys/power/disk ] && \
grep -q disk /sys/power/state && \
[ -c /dev/snapshot ] &&
command_exists s2disk; then
HIBERNATE_MODULE="uswsusp"
do_hibernate()
{
s2disk
}
fi
if [ -z "$SUSPEND_HYBRID_MODULE" ] &&
grep -q mem /sys/power/state && \
command_exists s2both && \
check_hibernate; then
SUSPEND_HYBRID_MODULE="uswsusp"
do_suspend_hybrid()
{
uswsusp_get_quirks
s2both --force $OPTS
}
if [ "$METHOD" = "suspend_hybrid" ]; then
add_before_hooks uswsusp_hooks
add_module_help uswsusp_help
fi
fi
Еще одно распространенное решение, которое вы можете использовать hybrid-sleep
(как это делает Mac OS). Если ваш компьютер поддерживает спящий режим, вы можете использовать эту функцию:
systemctl hybrid-sleep
Эта команда должна приостанавливать и отправлять на диск (спящий режим) компьютер , Через некоторое время компьютер выключится (при включении он будет использовать файлы гибернации для пробуждения).
ps: Я знаю, что это не совсем то, что опубликовано OP, но оно довольно близко
Вот мой рецепт (протестировал его на двух ноутбуках Ubuntu 16.04):
Поместите этот скрипт где угодно (я положил его на root, /syspend.sh
) и сделать его исполняемым ( chmod + x /suspend.sh
)
TIMELOG = / tmp / authibernate.log ALARM = $ (tail -n 1 $ TIMELOG) SLEEPTIME = 5000 #edit эту строку для изменения таймера, например 2 часа "$ ((2 * 60 * 60)), если [[$ 1 ==" resume "]], тогда если [[$ (date +% s) -ge $ (($ ALARM + $ SLEEPTIME))]] затем echo "hibernate triggered $ (date +% H:% M:% S)" & gt; & gt; $ TIMELOG systemctl hibernate 2 & gt; & gt; & gt; $ TIMELOG else echo "normal wakeup $ (date +% H:% M:% S)" & gt; $ $ TIMELOG fiifif [[$ 1 == "suspend"]] затем echo "$ (date +% s)" & GT; & GT; $ TIMELOG rtcwake -m no -s $ SLEEPTIME fi
Затем создайте цель systemd: # touch /etc/systemd/system/suspend-to-sleep.target
Вставьте этот контент:
# / etc / systemd / system / suspend-to-hibernate.service [Unit] Описание = Задержка спящего триггера Before = suspend.target Конфликты = hibernate.target hybrid-suspend .target StopWhenUnneeded = true [Service] Тип = oneshot RemainAfterExit = yes ExecStart = / bin / bash /suspend.sh приостановить ExecStop = / bin / bash /suspend.sh wakeup [Установить] WantedBy = sleep.target RequiredBy = suspend.target [ ! d4]
Затем включите его # systemctl enable suspend-to-sleep.target
.
Я столкнулся с проблемой на одном из ноутбуков: закрывающая крышка не запускала эту цель. Это было связано с xfce4-power-manager. Существует два способа решения этой проблемы. Первый - отредактировать файл /etc/systemd/logind.conf
и заменить HandleLidSwitch = игнорировать
с помощью HandleLidSwitch = suspend
. Но он будет системным, поэтому я просто добавил символическую ссылку на мой скрипт # ln -s /suspend.sh /etc/pm/sleep.d/0000rtchibernate
Кажется, что на Ubuntu 16.04 все немного отличается, поэтому шаги, которые я предпринял, чтобы заставить его работать, были:
systemctl hibernate
suspend.target
: sudo cp /lib/systemd/system/suspend.target /etc/systemd/system/suspend.target
Затем отредактируйте файл /etc/systemd/system/suspend.target
и добавьте строку: Requires=delayed-hibernation.service
в раздел [Unit]
этого файла. /etc/systemd/system/delayed-hibernation.service
со следующим содержимым: [Unit] Description=Delayed hibernation trigger Before=suspend.target Conflicts=hibernate.target hybrid-suspend.target StopWhenUnneeded=true [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/local/bin/delayed-hibernation.sh pre suspend ExecStop=/usr/local/bin/delayed-hibernation.sh post suspend [Install] WantedBy=sleep.target
/etc/delayed-hibernation.conf
для скрипта со следующим содержимым: # Configuration file for 'delayed-hibernation.sh' script # Specify the time in seconds to spend in sleep mode before the computer hibernates TIMEOUT=1200 #in seconds, gives 20 minutes
/usr/local/bin/delayed-hibernation.sh
с содержимым: #!/bin/bash # Script name: delayed-hibernation.sh # Purpose: Auto hibernates after a period of sleep # Edit the `TIMEOUT` variable in the `$hibernation_conf` file to set the number of seconds to sleep. hibernation_lock='/var/run/delayed-hibernation.lock' hibernation_fail='/var/run/delayed-hibernation.fail' hibernation_conf='/etc/delayed-hibernation.conf' # Checking the configuration file if [ ! -f $hibernation_conf ]; then echo "Missing configuration file ('$hibernation_conf'), aborting." exit 1 fi hibernation_timeout=$(grep "^[^#]" $hibernation_conf | grep "TIMEOUT=" | awk -F'=' '{ print $2 }' | awk -F'#' '{print $1}' | tr -d '[[ \t]]') if [ "$hibernation_timeout" = "" ]; then echo "Missing 'TIMEOUT' parameter from configuration file ('$hibernation_conf'), aborting." exit 1 elif [[ ! "$hibernation_timeout" =~ ^[0-9]+$ ]]; then echo "Bad 'TIMEOUT' parameter ('$hibernation_timeout') in configuration file ('$hibernation_conf'), expected number of seconds, aborting." exit 1 fi # Processing given parameters if [ "$2" = "suspend" ]; then curtime=$(date +%s) if [ "$1" = "pre" ]; then if [ -f $hibernation_fail ]; then echo "Failed hibernation detected, skipping setting RTC wakeup timer." else echo "Suspend detected. Recording time, set RTC timer" echo "$curtime" > $hibernation_lock rtcwake -m no -s $hibernation_timeout fi elif [ "$1" = "post" ]; then if [ -f $hibernation_fail ]; then rm $hibernation_fail fi if [ -f $hibernation_lock ]; then sustime=$(cat $hibernation_lock) rm $hibernation_lock if [ $(($curtime - $sustime)) -ge $hibernation_timeout ]; then echo "Automatic resume from suspend detected. Hibernating..." systemctl hibernate if [ $? -ne 0 ]; then echo "Automatic hibernation failed. Trying to suspend instead." touch $hibernation_fail systemctl suspend if [ $? -ne 0 ]; then echo "Automatic hibernation and suspend failover failed. Nothing else to try." fi fi else echo "Manual resume from suspend detected. Clearing RTC timer" rtcwake -m disable fi else echo "File '$hibernation_lock' was not found, nothing to do" fi else echo "Unrecognised first parameter: '$1', expected 'pre' or 'post'" fi else echo "This script is intended to be run by systemctl delayed-hibernation.service (expected second parameter: 'suspend')" fi
chmod 755 /usr/local/bin/delayed-hibernation.sh
Мне потребовалось довольно много до написания этого сценария на основе других ответов в этом потоке, которые я нашел в Интернете, например https://bbs.archlinux.org/viewtopic.php?pid=1554259
Моя версия скрипта пытается решить многие проблемы, например, снова приостановить работу, если спящий режим не был успешным, но снова не просыпаться после заранее определенного времени.
sudo systemctl daemon-reload
sudo systemctl enable delayed-hibernation.service
, чтобы убедиться, что используются новые службы / конфигурации. Чтобы проверить журнал обслуживания, вы можете использовать:
sudo systemctl status delayed-hibernation.service
blockquote>или для полного журнала использования службы:
sudo journalctl -u delayed-hibernation.service
blockquote>Обычный журнал, который я получаю от текущей службы:
mile@mile-ThinkPad:~$ sudo systemctl status delayed-hibernation.service ● delayed-hibernation.service - Delayed hibernation trigger Loaded: loaded (/etc/systemd/system/delayed-hibernation.service; enabled; vendor preset: enabled) Active: inactive (dead) Jun 09 20:35:42 mile-ThinkPad systemd[1]: Starting Delayed hibernation trigger... Jun 09 20:35:42 mile-ThinkPad delayed-hibernation.sh[2933]: Suspend detected. Recording time, set RTC timer Jun 09 20:35:42 mile-ThinkPad delayed-hibernation.sh[2933]: rtcwake: assuming RTC uses UTC ... Jun 09 20:35:42 mile-ThinkPad delayed-hibernation.sh[2933]: rtcwake: wakeup using /dev/rtc0 at Thu Jun 9 18:55:43 2016 Jun 09 20:55:44 mile-ThinkPad systemd[1]: Started Delayed hibernation trigger. Jun 09 20:55:44 mile-ThinkPad systemd[1]: delayed-hibernation.service: Unit not needed anymore. Stopping. Jun 09 20:55:44 mile-ThinkPad systemd[1]: Stopping Delayed hibernation trigger... Jun 09 20:55:44 mile-ThinkPad delayed-hibernation.sh[3093]: Automatic resume from suspend detected. Hibernating... Jun 09 20:55:44 mile-ThinkPad systemd[1]: Stopped Delayed hibernation trigger. mile@mile-ThinkPad:~$Итак, это было бы так, я надеюсь это действительно помогает кому-то, так как я провел дни, пытаясь выяснить правильную комбинацию конфигураций и версий сценариев, чтобы эта удобная функция работала.
На всякий случай, когда что-то пойдет не так во время pm-hibernate
, я предпочел бы приостановить работу компьютера, а не запускать его. Поэтому вы можете использовать:
... / usr / sbin / pm-hibernate || / usr / sbin / pm-suspend ...
Чтобы объяснить, как это работает (это похоже на Windows) простыми словами: машина не просыпается из режима ожидания, когда батарея разряжается, чтобы сохранить состояние машины в разделе подкачки, она экономит все на немедленно замените раздел в режиме ожидания, и когда батарея разрядится, он восстановится после этого, загрузив состояние из раздела подкачки (как это было бы в случае спячки).
AFAIK linux будет / должен использовать гибридный режим ожидания / спящий режим вместо «нормального» режима ожидания, если он знает, что он работает для вашего оборудования. Также возможно, что в настоящее время это отключено из-за слишком большого количества ошибок или чего-то еще ...;)
Если вам нравится экспериментировать, возможно, вы можете увидеть, сможете ли вы получить хорошие результаты с помощью pm-suspend -hybrid .
Если следующее говорит, что вам повезло, то в теории поддерживается гибридная приостановка в вашей системе:
pm-is-supported - -suspend-hybrid & amp; & amp; эхо "тебе повезло"
Вот обновленная версия ответа Derek Pressnall , которая работает с systemd и включает в себя предложение Элиа Кагана , просто поместите его в систему / usr / lib / systemd / -sleep / delayed_hibernation.sh и сделать его исполняемым:
#! / bin / bash hibernation_timeout = 1800 # 30 минут, если ["$ 2" = "suspend"]; затем curtime = $ (date +% s), если ["$ 1" = "pre"]; затем echo -e "[($ curtime) $ @] \nПри выполнении pre-suspend hook ..." & gt; & gt; gt; /tmp/delayed_hibernation.log echo "$ curtime" & gt; /var/run/delayed_hibernation.lock rtcwake -m no -s $ hibernation_timeout elif ["$ 1" = "post"]; затем echo -e "[($ curtime) $ @] \nВыпуск post-suspend hook ..." & gt; & gt; gt; /tmp/delayed_hibernation.log sustime = $ (cat /var/run/delayed_hibernation.lock), если [$ (($ curtime - $ sustime)) -ge $ hibernation_timeout]; затем echo -e «Автоматическое обнаружение возобновления, спящий режим. \n" & gt; & gt; & gt; & gt; /tmp/delayed_hibernation.log systemctl hibernate || systemctl suspend else echo -e «Обнаружено ручное возобновление, очистка аварийного сигнала RTC. \n" & gt; & gt; & gt; & gt; /tmp/delayed_hibernation.log rtcwake -m no -s 1 fi rm /var/run/delayed_hibernation.lock fi fi
Еще одно распространенное решение, которое вы можете использовать hybrid-sleep
(как это делает Mac OS). Если ваш компьютер поддерживает спящий режим, вы можете использовать эту функцию:
systemctl hybrid-sleep
Эта команда должна приостанавливать и отправлять на диск (спящий режим) компьютер , Через некоторое время компьютер выключится (при включении он будет использовать файлы гибернации для пробуждения).
ps: Я знаю, что это не совсем то, что опубликовано OP, но оно довольно близко
Вот мой рецепт (протестировал его на двух ноутбуках Ubuntu 16.04):
Поместите этот скрипт где угодно (я положил его на root, /syspend.sh
) и сделать его исполняемым ( chmod + x /suspend.sh
)
TIMELOG = / tmp / authibernate.log ALARM = $ (tail -n 1 $ TIMELOG) SLEEPTIME = 5000 #edit эту строку для изменения таймера, например 2 часа "$ ((2 * 60 * 60)), если [[$ 1 ==" resume "]], тогда если [[$ (date +% s) -ge $ (($ ALARM + $ SLEEPTIME))]] затем echo "hibernate triggered $ (date +% H:% M:% S)" & gt; & gt; $ TIMELOG systemctl hibernate 2 & gt; & gt; & gt; $ TIMELOG else echo "normal wakeup $ (date +% H:% M:% S)" & gt; $ $ TIMELOG fiifif [[$ 1 == "suspend"]] затем echo "$ (date +% s)" & GT; & GT; $ TIMELOG rtcwake -m no -s $ SLEEPTIME fi
Затем создайте цель systemd: # touch /etc/systemd/system/suspend-to-sleep.target
Вставьте этот контент:
# / etc / systemd / system / suspend-to-hibernate.service [Unit] Описание = Задержка спящего триггера Before = suspend.target Конфликты = hibernate.target hybrid-suspend .target StopWhenUnneeded = true [Service] Тип = oneshot RemainAfterExit = yes ExecStart = / bin / bash /suspend.sh приостановить ExecStop = / bin / bash /suspend.sh wakeup [Установить] WantedBy = sleep.target RequiredBy = suspend.target [ ! d4]
Затем включите его # systemctl enable suspend-to-sleep.target
.
Я столкнулся с проблемой на одном из ноутбуков: закрывающая крышка не запускала эту цель. Это было связано с xfce4-power-manager. Существует два способа решения этой проблемы. Первый - отредактировать файл /etc/systemd/logind.conf
и заменить HandleLidSwitch = игнорировать
с помощью HandleLidSwitch = suspend
. Но он будет системным, поэтому я просто добавил символическую ссылку на мой скрипт # ln -s /suspend.sh /etc/pm/sleep.d/0000rtchibernate
Не забудьте chmod + x этот файл, сделайте его исполняемым.
Есть еще одно решение без rtcwake, используя wakealarm в / sys / class / rtc / rtc0. Использовать устаревший код в pm-functions (/ usr / lib / pm-utils) после комментариев #, поскольку ядро не поддерживает напрямую ..., (потому что текущее ядро (после чего-то 3.6) напрямую поддерживает). Верните этот код и добавьте в do_suspend () вместо do_suspend_hybrid ().
Устаревший код (приостановить, затем спящий режим, когда вызывается suspend_hybrid):
# since the kernel does not directly support hybrid sleep, we do
# something else -- suspend and schedule an alarm to go into
# hibernate if we have slept long enough.
# Only do this if we do not need to do any special video hackery on resume
# from hibernate, though.
if [ -z "$SUSPEND_HYBRID_MODULE" -a -w "$PM_RTC/wakealarm" ] && \
check_suspend && check_hibernate && ! is_set $HIBERNATE_RESUME_POST_VIDEO; \
then
SUSPEND_HYBRID_MODULE="kernel"
do_suspend_hybrid() {
WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
echo >"$PM_RTC/wakealarm"
echo $WAKETIME > "$PM_RTC/wakealarm"
if do_suspend; then
NOW=$(cat "$PM_RTC/since_epoch")
if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ]; then
log "Woken by RTC alarm, hibernating."
# if hibernate fails for any reason, go back to suspend.
do_hibernate || do_suspend
else
echo > "$PM_RTC/wakealarm"
fi
else
# if we cannot suspend, just try to hibernate.
do_hibernate
fi
}
fi
Рекомендуется. Еще проще использовать uswsusp в то же время максимизировать выгоду s2both, т. Е. S2both при приостановке. Поместите восстановленный код в do_suspend () часть модуля uswsusp (/usr/lib/pm-utils/module.d).
Возвращенный код (suspend_hybrid при вызове suspend):
WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
echo >"$PM_RTC/wakealarm"
echo $WAKETIME > "$PM_RTC/wakealarm"
if do_suspend_hybrid; then
NOW=$(cat "$PM_RTC/since_epoch")
if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ]; then
log "Woken by RTC alarm, hibernating."
# if hibernate fails for any reason, go back to suspend_hybrid.
do_hibernate || do_suspend_hybrid
else
echo > "$PM_RTC/wakealarm"
fi
else
# when do_suspend is being called, convert to suspend_hybrid.
do_suspend_hybrid
fi
С помощью uswsusp мы можем видеть прогресс suspend / hibernate и обратный процесс, отображаемый в тексте, даже мы можем прервите его, нажав обратное пространство. Без uswsusp, suspend / hibernate просто появляются - исчезают досадно, особенно когда запускается wakealarm и выполняется спящий режим (s2disk в uswsusp). Установите период сна перед спящим в обычном месте в файле pm-functions.
# variables to handle hibernate after suspend support
PM_HIBERNATE_DELAY=900 # 15 minutes
PM_RTC=/sys/class/rtc/rtc0
Вот мода uswsusp: (помните, этот модуль вызывается из pm-функций, поэтому вставленные переменные одинаковы )
#!/bin/sh
# disable processing of 90chvt and 99video.
# s2ram and s2disk handle all this stuff internally.
uswsusp_hooks()
{
disablehook 99video "disabled by uswsusp"
}
# Since we disabled 99video, we need to take responsibility for proper
# quirk handling. s2ram handles all common video quirks internally,
# so all we have to do is translate the HAL standard options to s2ram options.
uswsusp_get_quirks()
{
OPTS=""
ACPI_SLEEP=0
for opt in $PM_CMDLINE; do
case "${opt##--quirk-}" in # just quirks, please
dpms-on) ;; # no-op
dpms-suspend) ;; # no-op
radeon-off) OPTS="$OPTS --radeontool" ;;
reset-brightness) ;; # no-op
s3-bios) ACPI_SLEEP=$(($ACPI_SLEEP + 1)) ;;
s3-mode) ACPI_SLEEP=$(($ACPI_SLEEP + 2)) ;;
vbe-post) OPTS="$OPTS --vbe_post" ;;
vbemode-restore) OPTS="$OPTS --vbe_mode" ;;
vbestate-restore) OPTS="$OPTS --vbe_save" ;;
vga-mode-3) ;; # no-op
save-pci) OPTS="$OPTS --pci_save" ;;
none) QUIRK_NONE="true" ;;
*) continue ;;
esac
done
[ $ACPI_SLEEP -ne 0 ] && OPTS="$OPTS --acpi_sleep $ACPI_SLEEP"
# if we were told to ignore quirks, do so.
# This is arguably not the best way to do things, but...
[ "$QUIRK_NONE" = "true" ] && OPTS=""
}
# Since we disabled 99video, we also need to handle displaying
# help info for the quirks we handle.
uswsusp_help()
{
echo # first echo makes it look nicer.
echo "s2ram video quirk handler options:"
echo
echo " --quirk-radeon-off"
echo " --quirk-s3-bios"
echo " --quirk-s3-mode"
echo " --quirk-vbe-post"
echo " --quirk-vbemode-restore"
echo " --quirk-vbestate-restore"
echo " --quirk-save-pci"
echo " --quirk-none"
}
# This idiom is used for all sleep methods. Only declare the actual
# do_ method if:
# 1: some other sleep module has not already done so, and
# 2: this sleep method can actually work on this system.
#
# For suspend, if SUSPEND_MODULE is set then something else has already
# implemented do_suspend. We could just check to see of do_suspend was
# already declared using command_exists, but using a dedicated environment
# variable makes it easier to debug when we have to know what sleep module
# ended up claiming ownership of a given sleep method.
if [ -z "$SUSPEND_MODULE" ] && command_exists s2ram && \
( grep -q mem /sys/power/state || \
( [ -c /dev/pmu ] && check_suspend_pmu; ); ); then
SUSPEND_MODULE="uswsusp"
do_suspend()
{
WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
echo >"$PM_RTC/wakealarm"
echo $WAKETIME > "$PM_RTC/wakealarm"
if do_suspend_hybrid; then
NOW=$(cat "$PM_RTC/since_epoch")
if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ]; then
log "Woken by RTC alarm, hibernating."
# if hibernate fails for any reason, go back to suspend_hybrid.
do_hibernate || do_suspend_hybrid
else
echo > "$PM_RTC/wakealarm"
fi
else
# when do_suspend is being called, convert to suspend_hybrid.
do_suspend_hybrid
fi
}
fi
if [ -z "$HIBERNATE_MODULE" ] && \
[ -f /sys/power/disk ] && \
grep -q disk /sys/power/state && \
[ -c /dev/snapshot ] &&
command_exists s2disk; then
HIBERNATE_MODULE="uswsusp"
do_hibernate()
{
s2disk
}
fi
if [ -z "$SUSPEND_HYBRID_MODULE" ] &&
grep -q mem /sys/power/state && \
command_exists s2both && \
check_hibernate; then
SUSPEND_HYBRID_MODULE="uswsusp"
do_suspend_hybrid()
{
uswsusp_get_quirks
s2both --force $OPTS
}
if [ "$METHOD" = "suspend_hybrid" ]; then
add_before_hooks uswsusp_hooks
add_module_help uswsusp_help
fi
fi
Кажется, что на Ubuntu 16.04 все немного отличается, поэтому шаги, которые я предпринял, чтобы заставить его работать, были:
systemctl hibernate
suspend.target
: sudo cp /lib/systemd/system/suspend.target /etc/systemd/system/suspend.target
Затем отредактируйте файл /etc/systemd/system/suspend.target
и добавьте строку: Requires=delayed-hibernation.service
в раздел [Unit]
этого файла. /etc/systemd/system/delayed-hibernation.service
со следующим содержимым: [Unit] Description=Delayed hibernation trigger Before=suspend.target Conflicts=hibernate.target hybrid-suspend.target StopWhenUnneeded=true [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/local/bin/delayed-hibernation.sh pre suspend ExecStop=/usr/local/bin/delayed-hibernation.sh post suspend [Install] WantedBy=sleep.target
/etc/delayed-hibernation.conf
для скрипта со следующим содержимым: # Configuration file for 'delayed-hibernation.sh' script # Specify the time in seconds to spend in sleep mode before the computer hibernates TIMEOUT=1200 #in seconds, gives 20 minutes
/usr/local/bin/delayed-hibernation.sh
с содержимым: #!/bin/bash # Script name: delayed-hibernation.sh # Purpose: Auto hibernates after a period of sleep # Edit the `TIMEOUT` variable in the `$hibernation_conf` file to set the number of seconds to sleep. hibernation_lock='/var/run/delayed-hibernation.lock' hibernation_fail='/var/run/delayed-hibernation.fail' hibernation_conf='/etc/delayed-hibernation.conf' # Checking the configuration file if [ ! -f $hibernation_conf ]; then echo "Missing configuration file ('$hibernation_conf'), aborting." exit 1 fi hibernation_timeout=$(grep "^[^#]" $hibernation_conf | grep "TIMEOUT=" | awk -F'=' '{ print $2 }' | awk -F'#' '{print $1}' | tr -d '[[ \t]]') if [ "$hibernation_timeout" = "" ]; then echo "Missing 'TIMEOUT' parameter from configuration file ('$hibernation_conf'), aborting." exit 1 elif [[ ! "$hibernation_timeout" =~ ^[0-9]+$ ]]; then echo "Bad 'TIMEOUT' parameter ('$hibernation_timeout') in configuration file ('$hibernation_conf'), expected number of seconds, aborting." exit 1 fi # Processing given parameters if [ "$2" = "suspend" ]; then curtime=$(date +%s) if [ "$1" = "pre" ]; then if [ -f $hibernation_fail ]; then echo "Failed hibernation detected, skipping setting RTC wakeup timer." else echo "Suspend detected. Recording time, set RTC timer" echo "$curtime" > $hibernation_lock rtcwake -m no -s $hibernation_timeout fi elif [ "$1" = "post" ]; then if [ -f $hibernation_fail ]; then rm $hibernation_fail fi if [ -f $hibernation_lock ]; then sustime=$(cat $hibernation_lock) rm $hibernation_lock if [ $(($curtime - $sustime)) -ge $hibernation_timeout ]; then echo "Automatic resume from suspend detected. Hibernating..." systemctl hibernate if [ $? -ne 0 ]; then echo "Automatic hibernation failed. Trying to suspend instead." touch $hibernation_fail systemctl suspend if [ $? -ne 0 ]; then echo "Automatic hibernation and suspend failover failed. Nothing else to try." fi fi else echo "Manual resume from suspend detected. Clearing RTC timer" rtcwake -m disable fi else echo "File '$hibernation_lock' was not found, nothing to do" fi else echo "Unrecognised first parameter: '$1', expected 'pre' or 'post'" fi else echo "This script is intended to be run by systemctl delayed-hibernation.service (expected second parameter: 'suspend')" fi
chmod 755 /usr/local/bin/delayed-hibernation.sh
Мне потребовалось довольно много до написания этого сценария на основе других ответов в этом потоке, которые я нашел в Интернете, например https://bbs.archlinux.org/viewtopic.php?pid=1554259
Моя версия скрипта пытается решить многие проблемы, например, снова приостановить работу, если спящий режим не был успешным, но снова не просыпаться после заранее определенного времени.
sudo systemctl daemon-reload
sudo systemctl enable delayed-hibernation.service
, чтобы убедиться, что используются новые службы / конфигурации. Чтобы проверить журнал обслуживания, вы можете использовать:
sudo systemctl status delayed-hibernation.service
blockquote>или для полного журнала использования службы:
sudo journalctl -u delayed-hibernation.service
blockquote>Обычный журнал, который я получаю от текущей службы:
mile@mile-ThinkPad:~$ sudo systemctl status delayed-hibernation.service ● delayed-hibernation.service - Delayed hibernation trigger Loaded: loaded (/etc/systemd/system/delayed-hibernation.service; enabled; vendor preset: enabled) Active: inactive (dead) Jun 09 20:35:42 mile-ThinkPad systemd[1]: Starting Delayed hibernation trigger... Jun 09 20:35:42 mile-ThinkPad delayed-hibernation.sh[2933]: Suspend detected. Recording time, set RTC timer Jun 09 20:35:42 mile-ThinkPad delayed-hibernation.sh[2933]: rtcwake: assuming RTC uses UTC ... Jun 09 20:35:42 mile-ThinkPad delayed-hibernation.sh[2933]: rtcwake: wakeup using /dev/rtc0 at Thu Jun 9 18:55:43 2016 Jun 09 20:55:44 mile-ThinkPad systemd[1]: Started Delayed hibernation trigger. Jun 09 20:55:44 mile-ThinkPad systemd[1]: delayed-hibernation.service: Unit not needed anymore. Stopping. Jun 09 20:55:44 mile-ThinkPad systemd[1]: Stopping Delayed hibernation trigger... Jun 09 20:55:44 mile-ThinkPad delayed-hibernation.sh[3093]: Automatic resume from suspend detected. Hibernating... Jun 09 20:55:44 mile-ThinkPad systemd[1]: Stopped Delayed hibernation trigger. mile@mile-ThinkPad:~$Итак, это было бы так, я надеюсь это действительно помогает кому-то, так как я провел дни, пытаясь выяснить правильную комбинацию конфигураций и версий сценариев, чтобы эта удобная функция работала.
Чтобы объяснить, как это работает (это похоже на Windows) простыми словами: машина не просыпается из режима ожидания, когда батарея разряжается, чтобы сохранить состояние машины в разделе подкачки, она экономит все на немедленно замените раздел в режиме ожидания, и когда батарея разрядится, он восстановится после этого, загрузив состояние из раздела подкачки (как это было бы в случае спячки).
AFAIK linux будет / должен использовать гибридный режим ожидания / спящий режим вместо «нормального» режима ожидания, если он знает, что он работает для вашего оборудования. Также возможно, что в настоящее время это отключено из-за слишком большого количества ошибок или чего-то еще ...;)
Если вам нравится экспериментировать, возможно, вы можете увидеть, сможете ли вы получить хорошие результаты с помощью pm-suspend -hybrid .
Если следующее говорит, что вам повезло, то в теории поддерживается гибридная приостановка в вашей системе:
pm-is-supported - -suspend-hybrid & amp; & amp; эхо "тебе повезло"
На всякий случай, когда что-то пойдет не так во время pm-hibernate
, я предпочел бы приостановить работу компьютера, а не запускать его. Поэтому вы можете использовать:
... / usr / sbin / pm-hibernate || / usr / sbin / pm-suspend ...
Вот обновленная версия ответа Derek Pressnall , которая работает с systemd и включает в себя предложение Элиа Кагана , просто поместите его в систему / usr / lib / systemd / -sleep / delayed_hibernation.sh и сделать его исполняемым:
#! / bin / bash hibernation_timeout = 1800 # 30 минут, если ["$ 2" = "suspend"]; затем curtime = $ (date +% s), если ["$ 1" = "pre"]; затем echo -e "[($ curtime) $ @] \nПри выполнении pre-suspend hook ..." & gt; & gt; gt; /tmp/delayed_hibernation.log echo "$ curtime" & gt; /var/run/delayed_hibernation.lock rtcwake -m no -s $ hibernation_timeout elif ["$ 1" = "post"]; затем echo -e "[($ curtime) $ @] \nВыпуск post-suspend hook ..." & gt; & gt; gt; /tmp/delayed_hibernation.log sustime = $ (cat /var/run/delayed_hibernation.lock), если [$ (($ curtime - $ sustime)) -ge $ hibernation_timeout]; затем echo -e «Автоматическое обнаружение возобновления, спящий режим. \n" & gt; & gt; & gt; & gt; /tmp/delayed_hibernation.log systemctl hibernate || systemctl suspend else echo -e «Обнаружено ручное возобновление, очистка аварийного сигнала RTC. \n" & gt; & gt; & gt; & gt; /tmp/delayed_hibernation.log rtcwake -m no -s 1 fi rm /var/run/delayed_hibernation.lock fi fi
Вас может заинтересовать s2both . Он предоставляется пакетом uswsusp
в Ubuntu 10.10. Он приостанавливается на диск, но вместо выключения система вместо этого помещает его в S3, который является режимом питания, обычно связанным с опцией «Приостановить» в Ubuntu. pm-suspend-hybrid - еще один инструмент, который пытается сделать то же самое.
Чтобы автоматизировать работу с крышкой, ознакомьтесь со следующим руководством, которое позволяет вам запускать произвольный скрипт при захвате события крышки:
http://ubuntuforums.org/showthread.php?t=1076486
Если вы случайно есть ThinkPad, manpage для tpctl
ссылается на аргумент, - pm-sedation-hibernate-from-suspend-timer
, который, кажется, обеспечивает функцию, ищу. Я бы предостерег вас от попытки использовать это на оборудовании, отличном от ThinkPad.
Для справки я просмотрел справочную страницу для hibernate.conf ; у него, казалось, не было каких-либо подходящих вариантов, но, возможно, стоило бы второго чтения.
Еще одно распространенное решение, которое вы можете использовать hybrid-sleep
(как это делает Mac OS). Если ваш компьютер поддерживает спящий режим, вы можете использовать эту функцию:
systemctl hybrid-sleep
Эта команда должна приостанавливать и отправлять на диск (спящий режим) компьютер , Через некоторое время компьютер выключится (при включении он будет использовать файлы гибернации для пробуждения).
ps: Я знаю, что это не совсем то, что опубликовано OP, но оно довольно близко
Вот мой рецепт (протестировал его на двух ноутбуках Ubuntu 16.04):
Поместите этот скрипт где угодно (я положил его на root, /syspend.sh
) и сделать его исполняемым ( chmod + x /suspend.sh
)
TIMELOG = / tmp / authibernate.log ALARM = $ (tail -n 1 $ TIMELOG) SLEEPTIME = 5000 #edit эту строку для изменения таймера, например 2 часа "$ ((2 * 60 * 60)), если [[$ 1 ==" resume "]], тогда если [[$ (date +% s) -ge $ (($ ALARM + $ SLEEPTIME))]] затем echo "hibernate triggered $ (date +% H:% M:% S)" & gt; & gt; $ TIMELOG systemctl hibernate 2 & gt; & gt; & gt; $ TIMELOG else echo "normal wakeup $ (date +% H:% M:% S)" & gt; $ $ TIMELOG fiifif [[$ 1 == "suspend"]] затем echo "$ (date +% s)" & GT; & GT; $ TIMELOG rtcwake -m no -s $ SLEEPTIME fi
Затем создайте цель systemd: # touch /etc/systemd/system/suspend-to-sleep.target
Вставьте этот контент:
# / etc / systemd / system / suspend-to-hibernate.service [Unit] Описание = Задержка спящего триггера Before = suspend.target Конфликты = hibernate.target hybrid-suspend .target StopWhenUnneeded = true [Service] Тип = oneshot RemainAfterExit = yes ExecStart = / bin / bash /suspend.sh приостановить ExecStop = / bin / bash /suspend.sh wakeup [Установить] WantedBy = sleep.target RequiredBy = suspend.target [ ! d4]
Затем включите его # systemctl enable suspend-to-sleep.target
.
Я столкнулся с проблемой на одном из ноутбуков: закрывающая крышка не запускала эту цель. Это было связано с xfce4-power-manager. Существует два способа решения этой проблемы. Первый - отредактировать файл /etc/systemd/logind.conf
и заменить HandleLidSwitch = игнорировать
с помощью HandleLidSwitch = suspend
. Но он будет системным, поэтому я просто добавил символическую ссылку на мой скрипт # ln -s /suspend.sh /etc/pm/sleep.d/0000rtchibernate
Не забудьте chmod + x этот файл, сделайте его исполняемым.
Есть еще одно решение без rtcwake, используя wakealarm в / sys / class / rtc / rtc0. Использовать устаревший код в pm-functions (/ usr / lib / pm-utils) после комментариев #, поскольку ядро не поддерживает напрямую ..., (потому что текущее ядро (после чего-то 3.6) напрямую поддерживает). Верните этот код и добавьте в do_suspend () вместо do_suspend_hybrid ().
Устаревший код (приостановить, затем спящий режим, когда вызывается suspend_hybrid):
# since the kernel does not directly support hybrid sleep, we do
# something else -- suspend and schedule an alarm to go into
# hibernate if we have slept long enough.
# Only do this if we do not need to do any special video hackery on resume
# from hibernate, though.
if [ -z "$SUSPEND_HYBRID_MODULE" -a -w "$PM_RTC/wakealarm" ] && \
check_suspend && check_hibernate && ! is_set $HIBERNATE_RESUME_POST_VIDEO; \
then
SUSPEND_HYBRID_MODULE="kernel"
do_suspend_hybrid() {
WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
echo >"$PM_RTC/wakealarm"
echo $WAKETIME > "$PM_RTC/wakealarm"
if do_suspend; then
NOW=$(cat "$PM_RTC/since_epoch")
if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ]; then
log "Woken by RTC alarm, hibernating."
# if hibernate fails for any reason, go back to suspend.
do_hibernate || do_suspend
else
echo > "$PM_RTC/wakealarm"
fi
else
# if we cannot suspend, just try to hibernate.
do_hibernate
fi
}
fi
Рекомендуется. Еще проще использовать uswsusp в то же время максимизировать выгоду s2both, т. Е. S2both при приостановке. Поместите восстановленный код в do_suspend () часть модуля uswsusp (/usr/lib/pm-utils/module.d).
Возвращенный код (suspend_hybrid при вызове suspend):
WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
echo >"$PM_RTC/wakealarm"
echo $WAKETIME > "$PM_RTC/wakealarm"
if do_suspend_hybrid; then
NOW=$(cat "$PM_RTC/since_epoch")
if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ]; then
log "Woken by RTC alarm, hibernating."
# if hibernate fails for any reason, go back to suspend_hybrid.
do_hibernate || do_suspend_hybrid
else
echo > "$PM_RTC/wakealarm"
fi
else
# when do_suspend is being called, convert to suspend_hybrid.
do_suspend_hybrid
fi
С помощью uswsusp мы можем видеть прогресс suspend / hibernate и обратный процесс, отображаемый в тексте, даже мы можем прервите его, нажав обратное пространство. Без uswsusp, suspend / hibernate просто появляются - исчезают досадно, особенно когда запускается wakealarm и выполняется спящий режим (s2disk в uswsusp). Установите период сна перед спящим в обычном месте в файле pm-functions.
# variables to handle hibernate after suspend support
PM_HIBERNATE_DELAY=900 # 15 minutes
PM_RTC=/sys/class/rtc/rtc0
Вот мода uswsusp: (помните, этот модуль вызывается из pm-функций, поэтому вставленные переменные одинаковы )
#!/bin/sh
# disable processing of 90chvt and 99video.
# s2ram and s2disk handle all this stuff internally.
uswsusp_hooks()
{
disablehook 99video "disabled by uswsusp"
}
# Since we disabled 99video, we need to take responsibility for proper
# quirk handling. s2ram handles all common video quirks internally,
# so all we have to do is translate the HAL standard options to s2ram options.
uswsusp_get_quirks()
{
OPTS=""
ACPI_SLEEP=0
for opt in $PM_CMDLINE; do
case "${opt##--quirk-}" in # just quirks, please
dpms-on) ;; # no-op
dpms-suspend) ;; # no-op
radeon-off) OPTS="$OPTS --radeontool" ;;
reset-brightness) ;; # no-op
s3-bios) ACPI_SLEEP=$(($ACPI_SLEEP + 1)) ;;
s3-mode) ACPI_SLEEP=$(($ACPI_SLEEP + 2)) ;;
vbe-post) OPTS="$OPTS --vbe_post" ;;
vbemode-restore) OPTS="$OPTS --vbe_mode" ;;
vbestate-restore) OPTS="$OPTS --vbe_save" ;;
vga-mode-3) ;; # no-op
save-pci) OPTS="$OPTS --pci_save" ;;
none) QUIRK_NONE="true" ;;
*) continue ;;
esac
done
[ $ACPI_SLEEP -ne 0 ] && OPTS="$OPTS --acpi_sleep $ACPI_SLEEP"
# if we were told to ignore quirks, do so.
# This is arguably not the best way to do things, but...
[ "$QUIRK_NONE" = "true" ] && OPTS=""
}
# Since we disabled 99video, we also need to handle displaying
# help info for the quirks we handle.
uswsusp_help()
{
echo # first echo makes it look nicer.
echo "s2ram video quirk handler options:"
echo
echo " --quirk-radeon-off"
echo " --quirk-s3-bios"
echo " --quirk-s3-mode"
echo " --quirk-vbe-post"
echo " --quirk-vbemode-restore"
echo " --quirk-vbestate-restore"
echo " --quirk-save-pci"
echo " --quirk-none"
}
# This idiom is used for all sleep methods. Only declare the actual
# do_ method if:
# 1: some other sleep module has not already done so, and
# 2: this sleep method can actually work on this system.
#
# For suspend, if SUSPEND_MODULE is set then something else has already
# implemented do_suspend. We could just check to see of do_suspend was
# already declared using command_exists, but using a dedicated environment
# variable makes it easier to debug when we have to know what sleep module
# ended up claiming ownership of a given sleep method.
if [ -z "$SUSPEND_MODULE" ] && command_exists s2ram && \
( grep -q mem /sys/power/state || \
( [ -c /dev/pmu ] && check_suspend_pmu; ); ); then
SUSPEND_MODULE="uswsusp"
do_suspend()
{
WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
echo >"$PM_RTC/wakealarm"
echo $WAKETIME > "$PM_RTC/wakealarm"
if do_suspend_hybrid; then
NOW=$(cat "$PM_RTC/since_epoch")
if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ]; then
log "Woken by RTC alarm, hibernating."
# if hibernate fails for any reason, go back to suspend_hybrid.
do_hibernate || do_suspend_hybrid
else
echo > "$PM_RTC/wakealarm"
fi
else
# when do_suspend is being called, convert to suspend_hybrid.
do_suspend_hybrid
fi
}
fi
if [ -z "$HIBERNATE_MODULE" ] && \
[ -f /sys/power/disk ] && \
grep -q disk /sys/power/state && \
[ -c /dev/snapshot ] &&
command_exists s2disk; then
HIBERNATE_MODULE="uswsusp"
do_hibernate()
{
s2disk
}
fi
if [ -z "$SUSPEND_HYBRID_MODULE" ] &&
grep -q mem /sys/power/state && \
command_exists s2both && \
check_hibernate; then
SUSPEND_HYBRID_MODULE="uswsusp"
do_suspend_hybrid()
{
uswsusp_get_quirks
s2both --force $OPTS
}
if [ "$METHOD" = "suspend_hybrid" ]; then
add_before_hooks uswsusp_hooks
add_module_help uswsusp_help
fi
fi
Кажется, что на Ubuntu 16.04 все немного отличается, поэтому шаги, которые я предпринял, чтобы заставить его работать, были:
systemctl hibernate
suspend.target
: sudo cp /lib/systemd/system/suspend.target /etc/systemd/system/suspend.target
Затем отредактируйте файл /etc/systemd/system/suspend.target
и добавьте строку: Requires=delayed-hibernation.service
в раздел [Unit]
этого файла. /etc/systemd/system/delayed-hibernation.service
со следующим содержимым: [Unit] Description=Delayed hibernation trigger Before=suspend.target Conflicts=hibernate.target hybrid-suspend.target StopWhenUnneeded=true [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/local/bin/delayed-hibernation.sh pre suspend ExecStop=/usr/local/bin/delayed-hibernation.sh post suspend [Install] WantedBy=sleep.target
/etc/delayed-hibernation.conf
для скрипта со следующим содержимым: # Configuration file for 'delayed-hibernation.sh' script # Specify the time in seconds to spend in sleep mode before the computer hibernates TIMEOUT=1200 #in seconds, gives 20 minutes
/usr/local/bin/delayed-hibernation.sh
с содержимым: #!/bin/bash # Script name: delayed-hibernation.sh # Purpose: Auto hibernates after a period of sleep # Edit the `TIMEOUT` variable in the `$hibernation_conf` file to set the number of seconds to sleep. hibernation_lock='/var/run/delayed-hibernation.lock' hibernation_fail='/var/run/delayed-hibernation.fail' hibernation_conf='/etc/delayed-hibernation.conf' # Checking the configuration file if [ ! -f $hibernation_conf ]; then echo "Missing configuration file ('$hibernation_conf'), aborting." exit 1 fi hibernation_timeout=$(grep "^[^#]" $hibernation_conf | grep "TIMEOUT=" | awk -F'=' '{ print $2 }' | awk -F'#' '{print $1}' | tr -d '[[ \t]]') if [ "$hibernation_timeout" = "" ]; then echo "Missing 'TIMEOUT' parameter from configuration file ('$hibernation_conf'), aborting." exit 1 elif [[ ! "$hibernation_timeout" =~ ^[0-9]+$ ]]; then echo "Bad 'TIMEOUT' parameter ('$hibernation_timeout') in configuration file ('$hibernation_conf'), expected number of seconds, aborting." exit 1 fi # Processing given parameters if [ "$2" = "suspend" ]; then curtime=$(date +%s) if [ "$1" = "pre" ]; then if [ -f $hibernation_fail ]; then echo "Failed hibernation detected, skipping setting RTC wakeup timer." else echo "Suspend detected. Recording time, set RTC timer" echo "$curtime" > $hibernation_lock rtcwake -m no -s $hibernation_timeout fi elif [ "$1" = "post" ]; then if [ -f $hibernation_fail ]; then rm $hibernation_fail fi if [ -f $hibernation_lock ]; then sustime=$(cat $hibernation_lock) rm $hibernation_lock if [ $(($curtime - $sustime)) -ge $hibernation_timeout ]; then echo "Automatic resume from suspend detected. Hibernating..." systemctl hibernate if [ $? -ne 0 ]; then echo "Automatic hibernation failed. Trying to suspend instead." touch $hibernation_fail systemctl suspend if [ $? -ne 0 ]; then echo "Automatic hibernation and suspend failover failed. Nothing else to try." fi fi else echo "Manual resume from suspend detected. Clearing RTC timer" rtcwake -m disable fi else echo "File '$hibernation_lock' was not found, nothing to do" fi else echo "Unrecognised first parameter: '$1', expected 'pre' or 'post'" fi else echo "This script is intended to be run by systemctl delayed-hibernation.service (expected second parameter: 'suspend')" fi
chmod 755 /usr/local/bin/delayed-hibernation.sh
Мне потребовалось довольно много до написания этого сценария на основе других ответов в этом потоке, которые я нашел в Интернете, например https://bbs.archlinux.org/viewtopic.php?pid=1554259
Моя версия скрипта пытается решить многие проблемы, например, снова приостановить работу, если спящий режим не был успешным, но снова не просыпаться после заранее определенного времени.
sudo systemctl daemon-reload
sudo systemctl enable delayed-hibernation.service
, чтобы убедиться, что используются новые службы / конфигурации. Чтобы проверить журнал обслуживания, вы можете использовать:
sudo systemctl status delayed-hibernation.service
blockquote>или для полного журнала использования службы:
sudo journalctl -u delayed-hibernation.service
blockquote>Обычный журнал, который я получаю от текущей службы:
mile@mile-ThinkPad:~$ sudo systemctl status delayed-hibernation.service ● delayed-hibernation.service - Delayed hibernation trigger Loaded: loaded (/etc/systemd/system/delayed-hibernation.service; enabled; vendor preset: enabled) Active: inactive (dead) Jun 09 20:35:42 mile-ThinkPad systemd[1]: Starting Delayed hibernation trigger... Jun 09 20:35:42 mile-ThinkPad delayed-hibernation.sh[2933]: Suspend detected. Recording time, set RTC timer Jun 09 20:35:42 mile-ThinkPad delayed-hibernation.sh[2933]: rtcwake: assuming RTC uses UTC ... Jun 09 20:35:42 mile-ThinkPad delayed-hibernation.sh[2933]: rtcwake: wakeup using /dev/rtc0 at Thu Jun 9 18:55:43 2016 Jun 09 20:55:44 mile-ThinkPad systemd[1]: Started Delayed hibernation trigger. Jun 09 20:55:44 mile-ThinkPad systemd[1]: delayed-hibernation.service: Unit not needed anymore. Stopping. Jun 09 20:55:44 mile-ThinkPad systemd[1]: Stopping Delayed hibernation trigger... Jun 09 20:55:44 mile-ThinkPad delayed-hibernation.sh[3093]: Automatic resume from suspend detected. Hibernating... Jun 09 20:55:44 mile-ThinkPad systemd[1]: Stopped Delayed hibernation trigger. mile@mile-ThinkPad:~$Итак, это было бы так, я надеюсь это действительно помогает кому-то, так как я провел дни, пытаясь выяснить правильную комбинацию конфигураций и версий сценариев, чтобы эта удобная функция работала.
На всякий случай, когда что-то пойдет не так во время pm-hibernate
, я предпочел бы приостановить работу компьютера, а не запускать его. Поэтому вы можете использовать:
... / usr / sbin / pm-hibernate || / usr / sbin / pm-suspend ...
Чтобы объяснить, как это работает (это похоже на Windows) простыми словами: машина не просыпается из режима ожидания, когда батарея разряжается, чтобы сохранить состояние машины в разделе подкачки, она экономит все на немедленно замените раздел в режиме ожидания, и когда батарея разрядится, он восстановится после этого, загрузив состояние из раздела подкачки (как это было бы в случае спячки).
AFAIK linux будет / должен использовать гибридный режим ожидания / спящий режим вместо «нормального» режима ожидания, если он знает, что он работает для вашего оборудования. Также возможно, что в настоящее время это отключено из-за слишком большого количества ошибок или чего-то еще ...;)
Если вам нравится экспериментировать, возможно, вы можете увидеть, сможете ли вы получить хорошие результаты с помощью pm-suspend -hybrid .
Если следующее говорит, что вам повезло, то в теории поддерживается гибридная приостановка в вашей системе:
pm-is-supported - -suspend-hybrid & amp; & amp; эхо "тебе повезло"
Вот обновленная версия ответа Derek Pressnall , которая работает с systemd и включает в себя предложение Элиа Кагана , просто поместите его в систему / usr / lib / systemd / -sleep / delayed_hibernation.sh и сделать его исполняемым:
#! / bin / bash hibernation_timeout = 1800 # 30 минут, если ["$ 2" = "suspend"]; затем curtime = $ (date +% s), если ["$ 1" = "pre"]; затем echo -e "[($ curtime) $ @] \nПри выполнении pre-suspend hook ..." & gt; & gt; gt; /tmp/delayed_hibernation.log echo "$ curtime" & gt; /var/run/delayed_hibernation.lock rtcwake -m no -s $ hibernation_timeout elif ["$ 1" = "post"]; затем echo -e "[($ curtime) $ @] \nВыпуск post-suspend hook ..." & gt; & gt; gt; /tmp/delayed_hibernation.log sustime = $ (cat /var/run/delayed_hibernation.lock), если [$ (($ curtime - $ sustime)) -ge $ hibernation_timeout]; затем echo -e «Автоматическое обнаружение возобновления, спящий режим. \n" & gt; & gt; & gt; & gt; /tmp/delayed_hibernation.log systemctl hibernate || systemctl suspend else echo -e «Обнаружено ручное возобновление, очистка аварийного сигнала RTC. \n" & gt; & gt; & gt; & gt; /tmp/delayed_hibernation.log rtcwake -m no -s 1 fi rm /var/run/delayed_hibernation.lock fi fi
Вас может заинтересовать s2both . Он предоставляется пакетом uswsusp
в Ubuntu 10.10. Он приостанавливается на диск, но вместо выключения система вместо этого помещает его в S3, который является режимом питания, обычно связанным с опцией «Приостановить» в Ubuntu. pm-suspend-hybrid - еще один инструмент, который пытается сделать то же самое.
Чтобы автоматизировать работу с крышкой, ознакомьтесь со следующим руководством, которое позволяет вам запускать произвольный скрипт при захвате события крышки:
http://ubuntuforums.org/showthread.php?t=1076486
Если вы случайно есть ThinkPad, manpage для tpctl
ссылается на аргумент, - pm-sedation-hibernate-from-suspend-timer
, который, кажется, обеспечивает функцию, ищу. Я бы предостерег вас от попытки использовать это на оборудовании, отличном от ThinkPad.
Для справки я просмотрел справочную страницу для hibernate.conf ; у него, казалось, не было каких-либо подходящих вариантов, но, возможно, стоило бы второго чтения.
Еще одно распространенное решение, которое вы можете использовать hybrid-sleep
(как это делает Mac OS). Если ваш компьютер поддерживает спящий режим, вы можете использовать эту функцию:
systemctl hybrid-sleep
Эта команда должна приостанавливать и отправлять на диск (спящий режим) компьютер , Через некоторое время компьютер выключится (при включении он будет использовать файлы гибернации для пробуждения).
ps: Я знаю, что это не совсем то, что опубликовано OP, но оно довольно близко
Вот мой рецепт (протестировал его на двух ноутбуках Ubuntu 16.04):
Поместите этот скрипт где угодно (я положил его на root, /syspend.sh
) и сделать его исполняемым ( chmod + x /suspend.sh
)
TIMELOG = / tmp / authibernate.log ALARM = $ (tail -n 1 $ TIMELOG) SLEEPTIME = 5000 #edit эту строку для изменения таймера, например 2 часа "$ ((2 * 60 * 60)), если [[$ 1 ==" resume "]], тогда если [[$ (date +% s) -ge $ (($ ALARM + $ SLEEPTIME))]] затем echo "hibernate triggered $ (date +% H:% M:% S)" & gt; & gt; $ TIMELOG systemctl hibernate 2 & gt; & gt; & gt; $ TIMELOG else echo "normal wakeup $ (date +% H:% M:% S)" & gt; $ $ TIMELOG fiifif [[$ 1 == "suspend"]] затем echo "$ (date +% s)" & GT; & GT; $ TIMELOG rtcwake -m no -s $ SLEEPTIME fi
Затем создайте цель systemd: # touch /etc/systemd/system/suspend-to-sleep.target
Вставьте этот контент:
# / etc / systemd / system / suspend-to-hibernate.service [Unit] Описание = Задержка спящего триггера Before = suspend.target Конфликты = hibernate.target hybrid-suspend .target StopWhenUnneeded = true [Service] Тип = oneshot RemainAfterExit = yes ExecStart = / bin / bash /suspend.sh приостановить ExecStop = / bin / bash /suspend.sh wakeup [Установить] WantedBy = sleep.target RequiredBy = suspend.target [ ! d4]
Затем включите его # systemctl enable suspend-to-sleep.target
.
Я столкнулся с проблемой на одном из ноутбуков: закрывающая крышка не запускала эту цель. Это было связано с xfce4-power-manager. Существует два способа решения этой проблемы. Первый - отредактировать файл /etc/systemd/logind.conf
и заменить HandleLidSwitch = игнорировать
с помощью HandleLidSwitch = suspend
. Но он будет системным, поэтому я просто добавил символическую ссылку на мой скрипт # ln -s /suspend.sh /etc/pm/sleep.d/0000rtchibernate
Не забудьте chmod + x этот файл, сделайте его исполняемым.
Есть еще одно решение без rtcwake, используя wakealarm в / sys / class / rtc / rtc0. Использовать устаревший код в pm-functions (/ usr / lib / pm-utils) после комментариев #, поскольку ядро не поддерживает напрямую ..., (потому что текущее ядро (после чего-то 3.6) напрямую поддерживает). Верните этот код и добавьте в do_suspend () вместо do_suspend_hybrid ().
Устаревший код (приостановить, затем спящий режим, когда вызывается suspend_hybrid):
# since the kernel does not directly support hybrid sleep, we do
# something else -- suspend and schedule an alarm to go into
# hibernate if we have slept long enough.
# Only do this if we do not need to do any special video hackery on resume
# from hibernate, though.
if [ -z "$SUSPEND_HYBRID_MODULE" -a -w "$PM_RTC/wakealarm" ] && \
check_suspend && check_hibernate && ! is_set $HIBERNATE_RESUME_POST_VIDEO; \
then
SUSPEND_HYBRID_MODULE="kernel"
do_suspend_hybrid() {
WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
echo >"$PM_RTC/wakealarm"
echo $WAKETIME > "$PM_RTC/wakealarm"
if do_suspend; then
NOW=$(cat "$PM_RTC/since_epoch")
if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ]; then
log "Woken by RTC alarm, hibernating."
# if hibernate fails for any reason, go back to suspend.
do_hibernate || do_suspend
else
echo > "$PM_RTC/wakealarm"
fi
else
# if we cannot suspend, just try to hibernate.
do_hibernate
fi
}
fi
Рекомендуется. Еще проще использовать uswsusp в то же время максимизировать выгоду s2both, т. Е. S2both при приостановке. Поместите восстановленный код в do_suspend () часть модуля uswsusp (/usr/lib/pm-utils/module.d).
Возвращенный код (suspend_hybrid при вызове suspend):
WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
echo >"$PM_RTC/wakealarm"
echo $WAKETIME > "$PM_RTC/wakealarm"
if do_suspend_hybrid; then
NOW=$(cat "$PM_RTC/since_epoch")
if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ]; then
log "Woken by RTC alarm, hibernating."
# if hibernate fails for any reason, go back to suspend_hybrid.
do_hibernate || do_suspend_hybrid
else
echo > "$PM_RTC/wakealarm"
fi
else
# when do_suspend is being called, convert to suspend_hybrid.
do_suspend_hybrid
fi
С помощью uswsusp мы можем видеть прогресс suspend / hibernate и обратный процесс, отображаемый в тексте, даже мы можем прервите его, нажав обратное пространство. Без uswsusp, suspend / hibernate просто появляются - исчезают досадно, особенно когда запускается wakealarm и выполняется спящий режим (s2disk в uswsusp). Установите период сна перед спящим в обычном месте в файле pm-functions.
# variables to handle hibernate after suspend support
PM_HIBERNATE_DELAY=900 # 15 minutes
PM_RTC=/sys/class/rtc/rtc0
Вот мода uswsusp: (помните, этот модуль вызывается из pm-функций, поэтому вставленные переменные одинаковы )
#!/bin/sh
# disable processing of 90chvt and 99video.
# s2ram and s2disk handle all this stuff internally.
uswsusp_hooks()
{
disablehook 99video "disabled by uswsusp"
}
# Since we disabled 99video, we need to take responsibility for proper
# quirk handling. s2ram handles all common video quirks internally,
# so all we have to do is translate the HAL standard options to s2ram options.
uswsusp_get_quirks()
{
OPTS=""
ACPI_SLEEP=0
for opt in $PM_CMDLINE; do
case "${opt##--quirk-}" in # just quirks, please
dpms-on) ;; # no-op
dpms-suspend) ;; # no-op
radeon-off) OPTS="$OPTS --radeontool" ;;
reset-brightness) ;; # no-op
s3-bios) ACPI_SLEEP=$(($ACPI_SLEEP + 1)) ;;
s3-mode) ACPI_SLEEP=$(($ACPI_SLEEP + 2)) ;;
vbe-post) OPTS="$OPTS --vbe_post" ;;
vbemode-restore) OPTS="$OPTS --vbe_mode" ;;
vbestate-restore) OPTS="$OPTS --vbe_save" ;;
vga-mode-3) ;; # no-op
save-pci) OPTS="$OPTS --pci_save" ;;
none) QUIRK_NONE="true" ;;
*) continue ;;
esac
done
[ $ACPI_SLEEP -ne 0 ] && OPTS="$OPTS --acpi_sleep $ACPI_SLEEP"
# if we were told to ignore quirks, do so.
# This is arguably not the best way to do things, but...
[ "$QUIRK_NONE" = "true" ] && OPTS=""
}
# Since we disabled 99video, we also need to handle displaying
# help info for the quirks we handle.
uswsusp_help()
{
echo # first echo makes it look nicer.
echo "s2ram video quirk handler options:"
echo
echo " --quirk-radeon-off"
echo " --quirk-s3-bios"
echo " --quirk-s3-mode"
echo " --quirk-vbe-post"
echo " --quirk-vbemode-restore"
echo " --quirk-vbestate-restore"
echo " --quirk-save-pci"
echo " --quirk-none"
}
# This idiom is used for all sleep methods. Only declare the actual
# do_ method if:
# 1: some other sleep module has not already done so, and
# 2: this sleep method can actually work on this system.
#
# For suspend, if SUSPEND_MODULE is set then something else has already
# implemented do_suspend. We could just check to see of do_suspend was
# already declared using command_exists, but using a dedicated environment
# variable makes it easier to debug when we have to know what sleep module
# ended up claiming ownership of a given sleep method.
if [ -z "$SUSPEND_MODULE" ] && command_exists s2ram && \
( grep -q mem /sys/power/state || \
( [ -c /dev/pmu ] && check_suspend_pmu; ); ); then
SUSPEND_MODULE="uswsusp"
do_suspend()
{
WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
echo >"$PM_RTC/wakealarm"
echo $WAKETIME > "$PM_RTC/wakealarm"
if do_suspend_hybrid; then
NOW=$(cat "$PM_RTC/since_epoch")
if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ]; then
log "Woken by RTC alarm, hibernating."
# if hibernate fails for any reason, go back to suspend_hybrid.
do_hibernate || do_suspend_hybrid
else
echo > "$PM_RTC/wakealarm"
fi
else
# when do_suspend is being called, convert to suspend_hybrid.
do_suspend_hybrid
fi
}
fi
if [ -z "$HIBERNATE_MODULE" ] && \
[ -f /sys/power/disk ] && \
grep -q disk /sys/power/state && \
[ -c /dev/snapshot ] &&
command_exists s2disk; then
HIBERNATE_MODULE="uswsusp"
do_hibernate()
{
s2disk
}
fi
if [ -z "$SUSPEND_HYBRID_MODULE" ] &&
grep -q mem /sys/power/state && \
command_exists s2both && \
check_hibernate; then
SUSPEND_HYBRID_MODULE="uswsusp"
do_suspend_hybrid()
{
uswsusp_get_quirks
s2both --force $OPTS
}
if [ "$METHOD" = "suspend_hybrid" ]; then
add_before_hooks uswsusp_hooks
add_module_help uswsusp_help
fi
fi
Кажется, что на Ubuntu 16.04 все немного отличается, поэтому шаги, которые я предпринял, чтобы заставить его работать, были:
systemctl hibernate
suspend.target
: sudo cp /lib/systemd/system/suspend.target /etc/systemd/system/suspend.target
Затем отредактируйте файл /etc/systemd/system/suspend.target
и добавьте строку: Requires=delayed-hibernation.service
в раздел [Unit]
этого файла. /etc/systemd/system/delayed-hibernation.service
со следующим содержимым: [Unit] Description=Delayed hibernation trigger Before=suspend.target Conflicts=hibernate.target hybrid-suspend.target StopWhenUnneeded=true [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/local/bin/delayed-hibernation.sh pre suspend ExecStop=/usr/local/bin/delayed-hibernation.sh post suspend [Install] WantedBy=sleep.target
/etc/delayed-hibernation.conf
для скрипта со следующим содержимым: # Configuration file for 'delayed-hibernation.sh' script # Specify the time in seconds to spend in sleep mode before the computer hibernates TIMEOUT=1200 #in seconds, gives 20 minutes
/usr/local/bin/delayed-hibernation.sh
с содержимым: #!/bin/bash # Script name: delayed-hibernation.sh # Purpose: Auto hibernates after a period of sleep # Edit the `TIMEOUT` variable in the `$hibernation_conf` file to set the number of seconds to sleep. hibernation_lock='/var/run/delayed-hibernation.lock' hibernation_fail='/var/run/delayed-hibernation.fail' hibernation_conf='/etc/delayed-hibernation.conf' # Checking the configuration file if [ ! -f $hibernation_conf ]; then echo "Missing configuration file ('$hibernation_conf'), aborting." exit 1 fi hibernation_timeout=$(grep "^[^#]" $hibernation_conf | grep "TIMEOUT=" | awk -F'=' '{ print $2 }' | awk -F'#' '{print $1}' | tr -d '[[ \t]]') if [ "$hibernation_timeout" = "" ]; then echo "Missing 'TIMEOUT' parameter from configuration file ('$hibernation_conf'), aborting." exit 1 elif [[ ! "$hibernation_timeout" =~ ^[0-9]+$ ]]; then echo "Bad 'TIMEOUT' parameter ('$hibernation_timeout') in configuration file ('$hibernation_conf'), expected number of seconds, aborting." exit 1 fi # Processing given parameters if [ "$2" = "suspend" ]; then curtime=$(date +%s) if [ "$1" = "pre" ]; then if [ -f $hibernation_fail ]; then echo "Failed hibernation detected, skipping setting RTC wakeup timer." else echo "Suspend detected. Recording time, set RTC timer" echo "$curtime" > $hibernation_lock rtcwake -m no -s $hibernation_timeout fi elif [ "$1" = "post" ]; then if [ -f $hibernation_fail ]; then rm $hibernation_fail fi if [ -f $hibernation_lock ]; then sustime=$(cat $hibernation_lock) rm $hibernation_lock if [ $(($curtime - $sustime)) -ge $hibernation_timeout ]; then echo "Automatic resume from suspend detected. Hibernating..." systemctl hibernate if [ $? -ne 0 ]; then echo "Automatic hibernation failed. Trying to suspend instead." touch $hibernation_fail systemctl suspend if [ $? -ne 0 ]; then echo "Automatic hibernation and suspend failover failed. Nothing else to try." fi fi else echo "Manual resume from suspend detected. Clearing RTC timer" rtcwake -m disable fi else echo "File '$hibernation_lock' was not found, nothing to do" fi else echo "Unrecognised first parameter: '$1', expected 'pre' or 'post'" fi else echo "This script is intended to be run by systemctl delayed-hibernation.service (expected second parameter: 'suspend')" fi
chmod 755 /usr/local/bin/delayed-hibernation.sh
Мне потребовалось довольно много до написания этого сценария на основе других ответов в этом потоке, которые я нашел в Интернете, например https://bbs.archlinux.org/viewtopic.php?pid=1554259
Моя версия скрипта пытается решить многие проблемы, например, снова приостановить работу, если спящий режим не был успешным, но снова не просыпаться после заранее определенного времени.
sudo systemctl daemon-reload
sudo systemctl enable delayed-hibernation.service
, чтобы убедиться, что используются новые службы / конфигурации. Чтобы проверить журнал обслуживания, вы можете использовать:
sudo systemctl status delayed-hibernation.service
blockquote>или для полного журнала использования службы:
sudo journalctl -u delayed-hibernation.service
blockquote>Обычный журнал, который я получаю от текущей службы:
mile@mile-ThinkPad:~$ sudo systemctl status delayed-hibernation.service ● delayed-hibernation.service - Delayed hibernation trigger Loaded: loaded (/etc/systemd/system/delayed-hibernation.service; enabled; vendor preset: enabled) Active: inactive (dead) Jun 09 20:35:42 mile-ThinkPad systemd[1]: Starting Delayed hibernation trigger... Jun 09 20:35:42 mile-ThinkPad delayed-hibernation.sh[2933]: Suspend detected. Recording time, set RTC timer Jun 09 20:35:42 mile-ThinkPad delayed-hibernation.sh[2933]: rtcwake: assuming RTC uses UTC ... Jun 09 20:35:42 mile-ThinkPad delayed-hibernation.sh[2933]: rtcwake: wakeup using /dev/rtc0 at Thu Jun 9 18:55:43 2016 Jun 09 20:55:44 mile-ThinkPad systemd[1]: Started Delayed hibernation trigger. Jun 09 20:55:44 mile-ThinkPad systemd[1]: delayed-hibernation.service: Unit not needed anymore. Stopping. Jun 09 20:55:44 mile-ThinkPad systemd[1]: Stopping Delayed hibernation trigger... Jun 09 20:55:44 mile-ThinkPad delayed-hibernation.sh[3093]: Automatic resume from suspend detected. Hibernating... Jun 09 20:55:44 mile-ThinkPad systemd[1]: Stopped Delayed hibernation trigger. mile@mile-ThinkPad:~$Итак, это было бы так, я надеюсь это действительно помогает кому-то, так как я провел дни, пытаясь выяснить правильную комбинацию конфигураций и версий сценариев, чтобы эта удобная функция работала.
/ bin / systemctl hibernate
всегда будет возвращать 1 при запуске в сценарии systemd, хотя он отлично работает в командной строке.
– eugenhu
28 May 2018 в 09:21