![Linux:如何在睡眠一段时间后进入休眠状态](https://linux22.com/image/1279965/Linux%EF%BC%9A%E5%A6%82%E4%BD%95%E5%9C%A8%E7%9D%A1%E7%9C%A0%E4%B8%80%E6%AE%B5%E6%97%B6%E9%97%B4%E5%90%8E%E8%BF%9B%E5%85%A5%E4%BC%91%E7%9C%A0%E7%8A%B6%E6%80%81.png)
我怀念 Linux 的 Windows 功能之一如下:在 Windows 中,您合上笔记本电脑盖,系统将挂起到 RAM,一段时间后(可配置),计算机将自动唤醒并继续挂起到磁盘。我知道 Linux 中存在 suspend2both 模式,但该模式在电池耗尽之前挂起到磁盘,而这正是我想要避免的。
编辑:使用答案数据搜索后找到更详细的答案
https://askubuntu.com/questions/12383/how-to-go-automatically-from-suspend-into-hibernate
EDIT2:这些是我在 MSI Wind U100 上使用 Ubuntu 11.04 所遵循的步骤。
首先:我安装了 tuxonice,因为我的上网本无法使用休眠功能。但副作用是休眠和唤醒过程非常快而且非常稳定。唯一的缺点是休眠/恢复时的显示为文本模式。安装 tuxonice 最简单的方法是添加相应的 ppa:https://launchpad.net/~tuxonice/+archive/ppa
一旦休眠工作,这个脚本就会发挥所有魔力
#!/bin/bash
# Script name: /etc/pm/sleep.d/00rtchibernate
# Purpose: Auto hibernates after a period of sleep
# Edit the "autohibernate" variable below to set the number of seconds to sleep.
curtime=$(date +%s)
autohibernate=7200
echo "$curtime $1" >>/tmp/autohibernate.log
if [ "$1" = "suspend" ]
then
# Suspending. Record current time, and set a wake up timer.
echo "$curtime" >/var/run/pm-utils/locks/rtchibernate.lock
rtcwake -m no -s $autohibernate
fi
if [ "$1" = "resume" ]
then
# Coming out of sleep
sustime=$(cat /var/run/pm-utils/locks/rtchibernate.lock)
rm /var/run/pm-utils/locks/rtchibernate.lock
# Did we wake up due to the rtc timer above?
if [ $(($curtime - $sustime)) -ge $autohibernate ]
then
# Then hibernate
rm /var/run/pm-utils/locks/pm-suspend.lock
/usr/sbin/pm-hibernate
else
# Otherwise cancel the rtc timer and wake up normally.
rtcwake -m no -s 1
fi
fi
通过修改自动休眠值,您可以更改机器唤醒并立即进入休眠状态的睡眠时间
注意:您可能必须安装 rtcwake,我已经安装了,但我不记得我是否自己安装了该软件包。
答案1
对于使用 的其他发行版,例如 CentOS、Fedor 或 Redhat systemd
。我们需要更改脚本的位置,而不是将其放在/etc/pm/sleep.d/
使用的位置,/usr/lib/systemd/system-sleep/
以使其可执行。0000rtchibernate.sh
chmod +x
最后,脚本中还需要进行一些调整,以使其与兼容systemd
。为了简单起见,我给出了完整的重写脚本
#!/bin/bash
# Script name: /usr/lib/systemd/system-sleep/0000rtchibernate
# Purpose: Auto hibernates after a period of sleep
# Edit the "autohibernate" variable below to set the number of seconds to sleep.
curtime=$(date +%s)
autohibernate=3600 #number is second
lock=/tmp/rtchibernate.lock
echo "$curtime $1" >>/tmp/autohibernate.log
if [ "$1" = "pre" ]
then
# Suspending. Record current time, and set a wake up timer.
echo "$curtime" > $lock
rtcwake -m no -s $autohibernate
fi
if [ "$1" = "post" ]
then
# Coming out of sleep
sustime=`cat $lock`
rm $lock
# Did we wake up due to the rtc timer above?
if [ $(($curtime - $sustime)) -ge $autohibernate ]
then
# Then hibernate
systemctl hibernate
else
# Otherwise cancel the rtc timer and wake up normally.
rtcwake -m no -s 1
fi
fi
该autohibernate
变量以秒为单位进行更改,以使其看起来合适。我希望我有所帮助
答案2
我猜你想要的是http://www.linuxcertif.com/man/8/rtcwake/它可以代替默认的 S2R(又称睡眠)程序。如果机器已经睡眠超过 20 分钟(比如说),这可以唤醒机器并触发休眠。
答案3
不要忘记chmod +x
该文件,使其可执行。
还有另一种不使用 的解决方案rtcwake
,wakealarm
在 中使用/sys/class/rtc/rtc0
。在注释 #since the kernel does not directly support ... 之后,在 pm-functions ( ) 中使用过时的代码/usr/lib/pm-utils
(因为当前内核(3.6 之后的版本)直接支持)。恢复该代码并将 替换为do_suspend()
part 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
ie的优势s2both when suspend
。将恢复的代码放在模块do_suspend()
的一部分( )。uswsusp
/usr/lib/pm-utils/module.d
恢复的代码(当调用suspend时suspend_hybrid):
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
,我们可以看到挂起/休眠的进度以及文本中显示的逆向过程,甚至可以通过按退格键中止它。如果没有uswsusp
,挂起/休眠只会令人烦恼地出现和消失,尤其是在wakealarm
触发和执行时hibernate
(s2disk
在 uswsusp 中)。在文件的通常位置设置休眠前的睡眠时间pm-functions
。
# variables to handle hibernate after suspend support
PM_HIBERNATE_DELAY=900 # 15 minutes
PM_RTC=/sys/class/rtc/rtc0
这是uswsusp
mod:(记住,这个模块是从这里调用的,pm-functions
所以插入的变量是相同的)
#!/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