Làm cách nào để tự động chuyển từ Đình chỉ vào Hibernate?


53

Có thể làm cho Ubuntu chuyển sang trạng thái Hibernate từ Suspend, hay còn gọi là "Đình chỉ an thần"?

Điều tôi đang tìm kiếm là đây:
Khi tôi đóng nắp, máy tính xách tay được đưa vào Đình chỉ. Sau đó, sau một thời gian xác định trước (ngay cả khi pin yếu) nếu tôi vẫn không sử dụng, nó nên tự đặt mình vào chế độ Ngủ đông để tiết kiệm pin.

Ví dụ: máy tính xách tay của tôi được thiết lập để vào trạng thái Tạm dừng khi tôi đóng nắp. Nếu sau đó tôi không sử dụng nó cho cả ngày, pin sẽ bị hỏng, bởi vì ngay cả ở chế độ treo, phần cứng vẫn tiêu thụ một lượng điện nhỏ và cuối cùng pin sẽ hết. Điều tôi muốn là có thể nói với Ubuntu rằng ngay cả khi bị treo, nó vẫn cần vào Hibernate sau vài giờ không hoạt động.

Windows có thể làm điều đó. Ubuntu có thể được lập trình để đi vào Chế độ chờ hoặc Hibernate trên bộ đếm thời gian, nhưng không phải cả hai.


Trong nghiên cứu của tôi, tôi đã tìm thấy cùng một chủ đề Linux Mint, nhưng "Đình chỉ an thần" không phải là một thuật ngữ chính thức của Microsoft cho tính năng đó và theo như tôi có thể nói được phát minh bởi người dùng diễn đàn Linux Mint đã đề cập đến nó.
ayan4m1

Có một cái tên tốt hơn cho tính năng đó?
Sergey Stadnik

Theo như tôi có thể nói, không có tên được chấp nhận phổ biến cho tính năng này. "Đình chỉ lai" được một số người sử dụng, "đình chỉ an thần" được sử dụng bởi một người dùng diễn đàn Linux Mint và tôi đã nghe "ngủ đông và đình chỉ" được sử dụng để đề cập đến quy trình trước đây. Microsoft chính thức gọi nó là "giấc ngủ lai", ít nhất là cho Windows 7.
ayan4m1

2
@ ayan4m1 Tôi nhận ra đây là một câu hỏi cũ, nhưng tôi nghĩ điều quan trọng là phải làm rõ điều này. Giấc ngủ của Hyrbid không giống như "Ngủ rồi ngủ đông sau một thời gian xác định". Giấc ngủ lai đơn giản trở thành ngủ đông khi mất điện, hết pin. Hành vi được mô tả bởi OP không yêu cầu bật chế độ Ngủ kết hợp.
Paul

Câu trả lời:


20

Trong Ubuntu 18.04, nó dễ dàng hơn nhiều. Trong systemd có sẵn một chế độ mới đình chỉ-sau đó ngủ đông . Để bắt đầu sử dụng chức năng này, bạn cần tạo một tập tin /etc/systemd/s ngủ.conf với nội dung tiếp theo:

[Sleep]
HibernateDelaySec=3600

Sau đó, bạn có thể kiểm tra nó bằng lệnh:

sudo systemctl suspend-then-hibernate

bạn có thể chỉnh sửa HibernateDelaySecđể giảm độ trễ để ngủ đông.


Nếu tất cả đều hoạt động tốt, bạn có thể thay đổi Hành động Đóng nắp, để thực hiện, bạn cần chỉnh sửa tệp /etc/systemd/logind.conf

Bạn cần tìm tùy chọn HandleLidSwitch=, bỏ ghi chú và thay đổi thành HandleLidSwitch=suspend-then-hibernate. Sau đó, bạn cần khởi động lại dịch vụ logind systemd (cảnh báo! Phiên người dùng của bạn sẽ được khởi động lại) bằng lệnh tiếp theo:

sudo systemctl restart systemd-logind.service

Đó là tất cả! Bây giờ bạn có thể sử dụng chức năng tốt đẹp này.


Đây là vị trí trên. Sử dụng nó trên Pop! _OS 18.10 (còn gọi là Ubuntu 18.10).
eduncan911

Rực rỡ cảm ơn bạn! Liệu ngủ.conf có ảnh hưởng đến chế độ ngủ đông theo một cách nào đó không, hay nó chỉ ảnh hưởng đến đình chỉ-sau đó ngủ đông?
dùng2428107

@ user2428107 bạn có thể đọc về các tùy chọn trong systutorials.com/docs/linux/man/5-systemd-s ngủ
PRIHLOP

35

Giải pháp cho việc này rất đơn giản. Đầu tiên, sau khi đình chỉ và tiếp tục, chương trình đình chỉ chiều thực hiện một loạt các kịch bản trong /etc/pm/sleep.d/usr/lib/pm-utils/sleep.d. Vì vậy, giải pháp của tôi là thêm một tập lệnh thực hiện như sau:

  1. Sau khi tạm dừng, ghi lại thời gian hiện tại và đăng ký một sự kiện đánh thức bằng cách sử dụng rtcwake.
  2. Sau khi tiếp tục, kiểm tra thời gian hiện tại so với thời gian ghi lại từ trên. Nếu đủ thời gian đã trôi qua, thì có lẽ chúng ta đã thức dậy do sự kiện hẹn giờ rtc. Nếu không, chúng tôi thức dậy sớm do một sự kiện người dùng (chẳng hạn như mở màn hình máy tính xách tay).
  3. Nếu chúng tôi thức dậy do bộ đếm thời gian rtc, thì ngay lập tức ban hành lệnh "pm-hibernate" để chuyển sang chế độ ngủ đông.

Đây là một kịch bản làm điều này. Đặt tên cho nó 0000rtchibernatevà đặt nó trong /etc/pm/sleep.dthư mục (0000 rất quan trọng, để tập lệnh thực thi đầu tiên khi tạm ngưng và cuối cùng là tiếp tục).

#!/bin/bash
# Script name: /etc/pm/sleep.d/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=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

Hy vọng mã này xuất hiện trên bảng tin này (đây là bài viết đầu tiên của tôi ở đây).

Chỉnh sửa giá trị thời gian chờ autohibernate=7200ở trên cùng, tuy nhiên nhiều giây bạn sẽ ngủ trước khi ngủ đông. Giá trị hiện tại ở trên là 2 giờ. Lưu ý rằng máy tính xách tay của bạn S Wake thức dậy vào thời điểm đó trong vài giây, trong khi nó đang thực hiện chức năng ngủ đông.

Vì vậy, nếu bạn có kế hoạch đặt máy tính xách tay của bạn trong một trường hợp, đừng đình chỉ, nhưng thay vào đó ngủ đông. Nếu không, máy tính xách tay của bạn có thể quá nóng trong đặc biệt. nếu nó ở trong một hộp trượt phù hợp chặt chẽ (mặc dù nó sẽ chỉ bật trong vài giây đến một phút).

Tôi đã sử dụng phương pháp này trong vài ngày qua, cho đến nay nó đã thành công (và đã cứu tôi khỏi một cục pin chết chiều nay). Thưởng thức.

Đối với các bản phân phối Linux khác sử dụng systemdvà các phiên bản Ubuntu mới hơn, nó vẫn hoạt động nếu bạn đặt tập lệnh /usr/lib/systemd/system-sleepthay vì /etc/pm/sleep.d. Ngoài ra, thay thế /usr/sbin/pm-hibernatelệnh bằng systemctl hibernate.


Nó đã hoạt động ở đây, nhưng chỉ sau khi tôi mã hóa tệp để thêm X cho mọi người. Tôi là một người mới lớn và tôi đã mất 2 ngày để tìm ra. Kịch bản rất tốt và tôi hy vọng điều này sẽ giúp bất cứ ai có thể gặp vấn đề. Cảm ơn bạn.

2
Điều này sẽ tạo ra một gói Ubuntu / Debian hữu ích!
Petr Pudlák

Chỉ cần tự hỏi: điều này vẫn còn hiệu lực cho Ubuntu 13.04? Tôi cần chính xác giải pháp này nhưng tôi không muốn làm hỏng máy tính xách tay của vợ nếu nó phá vỡ mọi thứ trên các phiên bản mới hơn.
Torben Gundtofte-Bruun

Cảm ơn kịch bản. Hoạt động tốt với tôi trên Ubuntu 14.04! Một cải tiến sẽ là nếu máy tính xách tay thức dậy ngủ đông, nó có thể kiểm tra xem nó có được cắm vào nguồn AC không. Nếu vậy, tôi muốn nó đình chỉ một lần nữa thay vì ngủ đông. Việc khôi phục từ chế độ ngủ đông mất nhiều thời gian hơn và tôi không thực sự cần nó để ngủ đông khi được cắm vào ...
maddentim

Cảm ơn bạn rất nhiều!!!! Kịch bản này là ma thuật tôi đã mơ ước !!
yanpas

12

Để giải thích cách thức hoạt động của tính năng này (tương tự như Windows) bằng những từ đơn giản: máy không thức dậy từ chế độ chờ khi pin yếu để có thể lưu trạng thái máy vào phân vùng trao đổi, nó lưu mọi thứ vào phân vùng trao đổi ngay lập tức ở chế độ chờ và khi hết pin, nó sẽ phục hồi từ đó bằng cách tải trạng thái từ phân vùng trao đổi (như sẽ làm trong trường hợp bạn ngủ đông).

AFAIK linux sẽ / nên sử dụng chế độ chờ hỗn hợp / ngủ đông thay vì chế độ chờ "thông thường" nếu biết rằng nó hoạt động cho phần cứng của bạn. Hiện tại cũng có thể bị vô hiệu hóa do có quá nhiều lỗi hoặc thứ gì đó ...;)

Nếu bạn thích thử nghiệm, có lẽ bạn có thể xem liệu bạn có thể nhận được bất kỳ kết quả tốt nào với pm-đình chỉ-lai không .

Nếu những điều sau đây nói rằng bạn may mắn, thì về mặt lý thuyết, việc đình chỉ lai được hỗ trợ trên hệ thống của bạn:

pm-is-supported --suspend-hybrid && echo "you're lucky"

1
Dấu nháy đơn trong lệnh shell của bạn có thể gây hiểu lầm và khó hiểu ... xin vui lòng thoát khỏi nó.
ayan4m1

1
Bah, đó là những gì xảy ra khi bạn chỉnh sửa một dòng lệnh được nhúng bên trong văn bản khác, mà không nghĩ về nó như một dòng lệnh ... Cảm ơn & Đã sửa.
JanC

Không có vấn đề, yeah hiểu về các không gian khác nhau cho hai quá trình.
ayan4m1

6

Bạn có thể quan tâm đến s2both . Nó được cung cấp bởi gói uswsusptrong Ubuntu 10.10. Nó tạm dừng vào đĩa, nhưng thay vì tắt hệ thống, thay vào đó, hãy đặt nó vào S3, đây là chế độ nguồn thường được liên kết với tùy chọn "Tạm dừng" trong Ubuntu. pm-đình chỉ-lai là một công cụ khác có ý định làm điều tương tự.

Để tự động đóng nắp này, hãy xem hướng dẫn sau cho phép bạn chạy tập lệnh tùy ý khi bắt gặp sự kiện nắp:

http://ubuntuforums.org/showthread.php?t=1076486

Nếu bạn tình cờ có ThinkPad, trang hướng tpctldẫn để tham chiếu đến một đối số, --pm-sedation-hibernate-from-suspend-timerdường như cung cấp tính năng bạn đang tìm kiếm. Tôi sẽ cảnh báo bạn không nên thử điều này trên phần cứng không phải ThinkPad.

Để tham khảo, tôi đã xem qua trang web cho hibernate.conf ; nó dường như không có bất kỳ lựa chọn liên quan nào nhưng có thể đáng để đọc lần thứ hai.


5

Ubuntu 16.04 - từ tạm dừng / ngủ sang ngủ đông sau một thời gian xác định trước

Có vẻ như trên Ubuntu 16.04 mọi thứ hơi khác một chút, vì vậy các bước tôi đã thực hiện để làm cho nó hoạt động là:

  1. Đảm bảo ngủ đông hoạt động như mong đợi khi chạy

    systemctl hibernate
    
  2. Sao chép suspend.targettập tin gốc :

    sudo cp /lib/systemd/system/suspend.target /etc/systemd/system/suspend.target
    

    Sau đó chỉnh sửa tệp /etc/systemd/system/suspend.targetvà thêm dòng:

    Requires=delayed-hibernation.service
    

    đến [Unit]phần của tập tin đó.

  3. Tạo tập tin /etc/systemd/system/delayed-hibernation.servicevới nội dung sau:

[Đơn vị]
Mô tả = Kích hoạt chế độ ngủ đông bị trì hoãn
Trước = Suspend.target
Xung đột = hibernate.target hybrid-suspend.target
StopWhenUnneeded = true

[Dịch vụ]
Loại = oneshot
RemainAfterExit = có
ExecStart = / usr / local / bin / delay-hibernation.sh trước khi tạm ngưng
ExecStop = / usr / local / bin / delay-hibernation.sh đăng bài

[Tải về]
WantedBy = ngủ.target
  1. Tạo tập tin cấu hình /etc/delayed-hibernation.confcho tập lệnh với nội dung sau:
# Tệp cấu hình cho tập lệnh 'delay-hibernation.sh'

# Chỉ định thời gian tính bằng giây trong chế độ ngủ trước khi máy tính ngủ đông
TIMEOUT = 1200 #in giây, cho 20 phút
  1. Tạo kịch bản mà thực sự sẽ làm công việc khó khăn.

    Tạo tập tin /usr/local/bin/delayed-hibernation.shvới nội dung:

#! / bin / bash
# Tên tập lệnh: delay-hibernation.sh
# Mục đích: Tự động ngủ đông sau một thời gian ngủ
# Chỉnh sửa biến `TIMEOUT` trong tệp` $ hibernation_conf` để đặt số giây ngủ.

hibernation_lock = '/ var / run / delay-hibernation.lock'
hibernation_fail = '/ var / run / delay-hibernation.fail'
hibernation_conf = '/ etc / delay-hibernation.conf'

# Kiểm tra tập tin cấu hình
nếu như [ ! -f $ hibernation_conf]; sau đó
    echo "Thiếu tệp cấu hình ('$ hibernation_conf'), hủy bỏ."
    thoát 1
fi
hibernation_timeout = $ (grep "^ [^ #]" $ hibernation_conf | grep "TIME hiện =" '[[\ T]]')
if ["$ hibernation_timeout" = ""]; sau đó
    echo "Thiếu tham số 'TIMEOUT' từ tệp cấu hình ('$ hibernation_conf'), hủy bỏ."
    thoát 1
elif [[! "$ hibernation_timeout" = ~ ^ [0-9] + $]]; sau đó
    echo "Tham số 'TIMEOUT' xấu ('$ hibernation_timeout') trong tệp cấu hình ('$ hibernation_conf'), số giây dự kiến, hủy bỏ."
    thoát 1
fi

# Xử lý các tham số đã cho
if ["$ 2" = "đình chỉ"]; sau đó
    thời gian chờ = $ (ngày +% s)
    if ["$ 1" = "trước"]; sau đó
        if [-f $ hibernation_fail]; sau đó
            echo "Không tìm thấy chế độ ngủ đông, bỏ qua cài đặt hẹn giờ đánh thức RTC."
        khác
            echo "Tạm dừng phát hiện. Thời gian ghi, đặt bộ hẹn giờ RTC"
            tiếng vang "$ curtime"> $ hibernation_lock
            rtcwake -m no -s $ hibernation_timeout
        fi
    elif ["$ 1" = "bài"]; sau đó
        if [-f $ hibernation_fail]; sau đó
            rm $ hibernation_fail
        fi
        if [-f $ hibernation_lock]; sau đó
            sustime = $ (mèo $ hibernation_lock)
            rm $ hibernation_lock
            if [$ (($ curtime - $ sustime)) -ge $ hibernation_timeout]; sau đó
                echo "Tự động tiếp tục từ việc tạm dừng được phát hiện. Ngủ đông ..."
                ngủ đông systemctl
                nếu [$? -Một 0]; sau đó
                    echo "Tự động ngủ đông không thành công. Thay vào đó, cố gắng tạm dừng."
                    chạm vào $ hibernation_fail
                    đình chỉ hệ thống
                    nếu [$? -Một 0]; sau đó
                        echo "Tự động ngủ đông và tạm dừng chuyển đổi dự phòng thất bại. Không có gì khác để thử."
                    fi
                fi
            khác
                echo "Tiếp tục thủ công từ đình chỉ được phát hiện. Xóa bộ đếm thời gian RTC"
                rtcwake -m vô hiệu hóa
            fi
        khác
            echo "Không tìm thấy tệp '$ hibernation_lock', không có gì để làm"
        fi
    khác
        echo "Thông số đầu tiên không được nhận dạng: '$ 1', dự kiến ​​'trước' hoặc 'bài'"
    fi
khác
    echo "Tập lệnh này được dự định chạy bởi systemctl delay-hibernation.service (tham số thứ hai dự kiến: 'đình chỉ')"
fi
  1. Làm cho tập lệnh thực thi:
chmod 755 /usr/local/bin/delayed-hibernation.sh

Tôi đã mất khá nhiều cho đến khi viết kịch bản này dựa trên các câu trả lời khác trong chủ đề này, những thứ tôi tìm thấy trên internet như https://bbs.archlinux.org/viewtopic.php?pid=1554259

Phiên bản kịch bản của tôi cố gắng xử lý nhiều vấn đề như đình chỉ một lần nữa nếu ngủ đông không thành công nhưng không tỉnh lại sau thời gian xác định trước hết lần này đến lần khác.

  1. Bước cuối cùng tôi giả sử sẽ chỉ thực hiện

    sudo systemctl daemon-reload
    sudo systemctl enable delayed-hibernation.service 
    

    để đảm bảo dịch vụ / cấu hình mới đang được sử dụng.

Để kiểm tra nhật ký dịch vụ, bạn có thể sử dụng:

sudo systemctl status delay-hibernation.service

hoặc cho một bản ghi đầy đủ của việc sử dụng dịch vụ:

sudo Journalctl -u delay-hibernation.service

Một nhật ký bình thường tôi nhận được từ dịch vụ đang chạy là:

Mile @ Mile-ThinkPad: ~ $ sudo systemctl status delay-hibernation.service 
● trì hoãn ngủ đông. Dịch vụ - Kích hoạt chế độ ngủ đông bị trì hoãn
   Đã tải: đã tải (/etc/systemd/system/delayed-hibernation.service; enable; nhà cung cấp cài sẵn: đã bật)
   Hoạt động: không hoạt động (đã chết)

Ngày 09 tháng 6 20:35:42 dặm-ThinkPad systemd [1]: Bắt đầu kích hoạt chế độ ngủ đông bị trì hoãn ...
09 tháng 9 20:35:42 dặm-ThinkPad delay-hibernation.sh [2933]: Tạm dừng phát hiện. Thời gian ghi, đặt hẹn giờ RTC
Ngày 09 tháng 6 20:35:42 dặm-ThinkPad bị trì hoãn-hibernation.sh [2933]: rtcwake: giả sử RTC sử dụng UTC ...
Ngày 09 tháng 6 20:35:42 dặm-ThinkPad bị trì hoãn-hibernation.sh [2933]: rtcwake: thức dậy bằng cách sử dụng / dev / rtc0 tại Thu Jun 9 18:55:43 2016
Ngày 09 tháng 6 20:55:44 dặm-ThinkPad systemd [1]: Bắt đầu kích hoạt chế độ ngủ đông bị trì hoãn.
Ngày 09 tháng 6 20:55:44 dặm-ThinkPad systemd [1]: delay-hibernation.service: Đơn vị không cần thiết nữa. Dừng lại.
Ngày 09 tháng 6 20:55:44 dặm-ThinkPad systemd [1]: Dừng kích hoạt chế độ ngủ đông bị trì hoãn ...
Ngày 09 tháng 6 20:55:44 dặm-ThinkPad delay-hibernation.sh [3093]: Tự động tiếp tục từ việc tạm ngưng được phát hiện. Ngủ đông ...
Ngày 09 tháng 6 20:55:44 dặm-ThinkPad systemd [1]: Đã dừng kích hoạt chế độ ngủ đông bị trì hoãn.
dặm @ dặm-ThinkPad: ~ $ 

Vì vậy, đây sẽ là nó, tôi hy vọng nó thực sự giúp ích cho ai đó vì tôi đã dành nhiều ngày cố gắng tìm ra sự kết hợp đúng giữa cấu hình và phiên bản tập lệnh để làm cho tính năng tiện dụng này hoạt động.


Cảm ơn câu trả lời, điều này vẫn hoạt động như một cơ duyên trên Ubuntu 18.04. Tôi không thể làm cho các câu trả lời ở trên hoạt động, việc thực thi /bin/systemctl hibernatesẽ luôn trả về 1 khi chạy trong tập lệnh systemd, mặc dù nó hoạt động tốt trên dòng lệnh.
eugenhu

4

Chỉ trong trường hợp có sự cố xảy ra trong khi pm-hibernatetôi muốn đặt máy tính tạm ngưng hơn là để nó chạy. Vì vậy, bạn có thể sử dụng:

   ...
/usr/sbin/pm-hibernate || /usr/sbin/pm-suspend
   ...

3

Dưới đây là một phiên bản cập nhật của câu trả lời Derek Pressnall của mà làm việc với systemd và bao gồm đề nghị Eliah Kagan của , chỉ cần thả nó trong /usr/lib/systemd/system-sleep/delayed_hibernation.sh và làm cho nó thực thi:

#!/bin/bash

hibernation_timeout=1800  #30 minutes

if [ "$2" = "suspend" ]; then
    curtime=$(date +%s)
    if [ "$1" = "pre" ]; then
        echo -e "[($curtime) $@]\nExecuting pre-suspend hook..." >> /tmp/delayed_hibernation.log
        echo "$curtime" > /var/run/delayed_hibernation.lock
        rtcwake -m no -s $hibernation_timeout
    elif [ "$1" = "post" ]; then
        echo -e "[($curtime) $@]\nExecuting post-suspend hook..." >> /tmp/delayed_hibernation.log
        sustime=$(cat /var/run/delayed_hibernation.lock)
        if [ $(($curtime - $sustime)) -ge $hibernation_timeout ]; then
            echo -e "Automatic resume detected, hibernating.\n" >> /tmp/delayed_hibernation.log
            systemctl hibernate || systemctl suspend
        else
            echo -e "Manual resume detected, clearing RTC alarm.\n" >> /tmp/delayed_hibernation.log
            rtcwake -m no -s 1
        fi
        rm /var/run/delayed_hibernation.lock
    fi
fi

Điều này đã hoạt động rất tốt trong vài tháng vào ngày 15.10 nhưng có gì đó vào ngày 16.04 ngăn nó ngủ đông mặc dù tập lệnh vẫn chạy.
Sean

@Sean bạn đã thử cách giải quyết trong chủ đề này chưa?
Niccolò Maggioni

Cám ơn đã chỉ tôi hướng đi đúng. Tôi đã tạo một dịch vụ systemd (/etc/systemd/system/delayed-hibernation.service) đã tham chiếu tập lệnh ở trên sau đó sửa đổi /etc/systemd/system/suspend.target để yêu cầu dịch vụ hibernation.service bị trì hoãn.
Sean

2

Đây là công thức của tôi (đã thử nghiệm nó trên hai máy tính xách tay Ubuntu 16.04):

Đặt tập lệnh này bất cứ nơi nào bạn thích (tôi đặt nó vào thư mục gốc /syspend.sh) và làm cho tập lệnh thực thi ( 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

Sau đó tạo mục tiêu systemd: # touch /etc/systemd/system/suspend-to-sleep.target Dán nội dung này:

#/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

Sau đó kích hoạt nó # systemctl enable suspend-to-sleep.target.

Tôi đã gặp phải một vấn đề trên một trong những cuốn sổ: nắp đóng không kích hoạt mục tiêu này. Điều này là do xfce4-power-manager. Có hai cách để khắc phục vấn đề này. Việc đầu tiên là chỉnh sửa /etc/systemd/logind.conftập tin và thay thế HandleLidSwitch=ignorebằng HandleLidSwitch=suspend. Nhưng nó sẽ là toàn hệ thống, vì vậy tôi chỉ cần thêm symlink vào tập lệnh của mình# ln -s /suspend.sh /etc/pm/sleep.d/0000rtchibernate


1

Một cách giải quyết khác phổ biến hơn mà bạn có thể sử dụng hybrid-sleep(như Mac OS hiện). Nếu máy tính của bạn hỗ trợ ngủ đông, bạn có thể sử dụng tính năng này:

systemctl hybrid-sleep

Lệnh đó sẽ tạm dừng và gửi vào đĩa (ngủ đông) máy tính. Sau một thời gian máy tính sẽ tắt (khi bật, nó sẽ sử dụng các tệp ngủ đông để đánh thức).

ps: Tôi biết đó không chính xác là những gì OP đăng, nhưng nó khá gần


0

Đừng quên chmod + x tệp đó, làm cho nó thực thi được.

Có một giải pháp khác mà không cần rtcwake, sử dụng wakealarm trong / sys / class / rtc / rtc0. Sử dụng mã lỗi thời trong các hàm pm (/ usr / lib / pm-utils) sau khi các bình luận #since kernel không hỗ trợ trực tiếp ..., ('cos kernel hiện tại (sau 3.6 một cái gì đó) không hỗ trợ trực tiếp). Hoàn nguyên mã đó và đặt vào phần do_suspend () thay vì do_suspend_hy điều chỉnh ().

Mã lỗi thời (tạm dừng sau đó ngủ đông khi Suspend_hy điều chỉnh được gọi):

# 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

Đề nghị. Thậm chí dễ dàng hơn để sử dụng uswsusp trong khi đồng thời tối đa hóa lợi ích của s2both tức là s2both khi tạm ngưng. Đặt mã được hoàn nguyên trong một phần do_suspend () của mô đun uswsusp (/usr/lib/pm-utils/module.d).

Mã được hoàn nguyên (Suspend_hy điều chỉnh khi tạm ngừng được gọi):

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      

Với uswsusp, chúng ta có thể thấy tiến trình đình chỉ / ngủ đông và quá trình ngược được hiển thị trong văn bản, thậm chí chúng ta có thể hủy bỏ nó bằng cách nhấn backspace. Không có uswsusp, đình chỉ / ngủ đông chỉ xuất hiện biến mất một cách khó chịu, đặc biệt là khi wakealarm được kích hoạt và thực thi hibernate (s2disk trong uswsusp). Đặt thời gian ngủ trước khi ngủ đông ở vị trí thông thường trên tệp chức năng pm.

# variables to handle hibernate after suspend support
PM_HIBERNATE_DELAY=900  # 15 minutes
PM_RTC=/sys/class/rtc/rtc0

Đây là mod uswsusp: (hãy nhớ rằng mô-đun này được gọi từ các hàm pm nên các biến được chèn là như nhau)

#!/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  
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.