从暂停状态恢复时执行脚本的正确方法

从暂停状态恢复时执行脚本的正确方法

Ubuntu 20.04

我进行过多次搜索,寻找在从暂停状态恢复时执行脚本或命令的方法,并想出了几种不同的方法,例如所描述的这里- 这些对我都不起作用。

我发现的第一个方法是使用 pm-utils。显然这种方法已经被从 Ubuntu 中删除,从 15.04 左右开始

我发现的下一件事是使用systemd/系统睡眠- 这对我来说也不起作用。我尝试在 /usr/lib/systemd/system-sleep 目录中创建一个脚本,还尝试了 /lib/systemd/system-sleep 目录(它显然链接到 /usr/lib/systemd/system-sleep,因为其中一个的更改会出现在另一个中)。我还尝试修改已经存在的脚本,称为 hdparm - 这也不起作用(我所做的修改是,touch /tmp/xmodlog.log但文件从未出现)。

那么,有人能告诉我恢复时运行脚本或命令的正确方法是什么吗?

感谢任何意见/建议/网站 - 特别是那些带有详细说明和对沿途发生的事情的解释的...

编辑:

根据回答在 Matigo 的协助下,我做了以下工作:

在 /etc/pm/sleep.d 中我创建了一个名为 00xmodkey.sh 的脚本。我将以下脚本代码添加到此文件中,然后确保它由 root 拥有,并且具有执行权限。

脚本内容(尝试使用 sh 和 bash 作为 shell):

#!/bin/sh

case "${1}" in
    resume|thaw) 
        touch /tmp/xmodlog.log
        echo "$(date) - lib testing" >> /tmp/xmodlog.log
        ;;
esac

已验证的所有权和权限:

ls -l 00xmodkey.sh
-rwxr-xr-x 1 root root 257 Feb  4 22:49 00xmodkey.sh

然后我将系统置于挂起状态。等待约 20 秒。唤醒系统。在 /tmp 中查找名为 xmodlog.log 的文件。没有文件。

所以,我一定还遗漏了一些东西......

编辑2:

根据 blitzter47 的回复,我放置了一个/lib/systemd/system-sleep/名为 20xmodmap 的脚本,随后将其标记为可执行。脚本文件包含以下内容:

#!/bin/sh
# Remap a key to allow context menu access

case "$1" in
    post) 
        echo "$(date) - lib testing" >> /tmp/xmodlog.log
        ;;
    *)
        echo "$(date) - $(1) $(2) - lib testing" >> /tmp/xmodlog.log
        ;;
esac

exit 0

文件 xmodlog.log 从未出现在 /tmp 中,因此脚本可能有问题,或者脚本从未被执行。

编辑3:

根据下面的评论,我修改了脚本以明确指定命令路径,并使用touch而不是echo。结果没有变化。还尝试移动临时文件的位置,只是为了确保不会因为使用 而发生奇怪的事情/tmp,但同样没有变化。这是修改后的脚本:

#!/bin/sh
# Remap a key to allow context menu access

case "$1" in
    post) 
        /bin/touch /home/tracy/xmodlog.log
        ;;
    *)
        /bin/touch /home/tracy/xmodlog.log
        ;;
esac

exit 0

因此,即使所有内容都明确指定了路径,并使用我知道用户有权访问的文件夹(如果在系统环境中运行,系统应该可以访问任何内容),它似乎仍然无法正常工作。

编辑4:

请求“sudo systemctl status sleep.target suspend.target hibernate.target hybrid-sleep.target”的输出:

tracy@tracy-HP17:~$ sudo systemctl status sleep.target suspend.target hibernate.target hybrid-sleep.target
● sleep.target - Sleep
     Loaded: loaded (/lib/systemd/system/sleep.target; static; vendor preset: e>
     Active: inactive (dead)
       Docs: man:systemd.special(7)

● suspend.target - Suspend
     Loaded: loaded (/lib/systemd/system/suspend.target; static; vendor preset:>
     Active: inactive (dead)
       Docs: man:systemd.special(7)

● hibernate.target - Hibernate
     Loaded: loaded (/lib/systemd/system/hibernate.target; static; vendor prese>
     Active: inactive (dead)
       Docs: man:systemd.special(7)

● hybrid-sleep.target - Hybrid Suspend+Hibernate
     Loaded: loaded (/lib/systemd/system/hybrid-sleep.target; static; vendor pr>
     Active: inactive (dead)
       Docs: man:systemd.special(7)

编辑5:

因此,我进入并清理了脚本,并确保一切正常(从命令行运行有效)。以下是设置和运行脚本的命令和输出:

tracy@tracy-HP17:/usr/lib/systemd/system-sleep$ which ls
/usr/bin/ls
tracy@tracy-HP17:/usr/lib/systemd/system-sleep$ which echo
/usr/bin/echo
tracy@tracy-HP17:/usr/lib/systemd/system-sleep$ ls -la /lib/systemd/system-sleep
total 32
drwxr-xr-x  2 root root  4096 Mar  9 21:30 .
drwxr-xr-x 17 root root 12288 Jan 19 13:39 ..
-rwxr-xr-x  1 root root   405 Mar  9 21:22 20xmodmap
-rwxr-xr-x  1 root root   148 Feb 26 22:01 hdparm
-rw-r--r--  1 root root   404 Mar  9 20:54 holding.txt
-rwxr-xr-x  1 root root   219 Jul 21  2020 unattended-upgrades
tracy@tracy-HP17:/usr/lib/systemd/system-sleep$ nl 20xmodmap
     1  #!/bin/sh
     2  # Remap a key to allow context menu access
       
     3  /usr/bin/ls /home/tracy/TestScript/
       
     4  case "$1" in
     5      post) 
     6  #       /usr/bin/touch /home/tracy/TestScript/xmodlog.log
     7          /usr/bin/echo "post" > /home/tracy/TestScript/xmodlog.log
     8          ;;
     9      *)
    10  #       /usr/bin/touch /home/tracy/TestScript/xmodlog.log
    11          /usr/bin/echo "default" > /home/tracy/TestScript/xmodlog.log
    12          ;;
    13  esac
       
    14  /usr/bin/ls /home/tracy/TestScript/
       
    15  exit 0
tracy@tracy-HP17:/usr/lib/systemd/system-sleep$ ls /home/tracy/TestScript
tracy@tracy-HP17:/usr/lib/systemd/system-sleep$ sudo ./20xmodmap
[sudo] password for tracy: 
xmodlog.log
tracy@tracy-HP17:/usr/lib/systemd/system-sleep$ ls /home/tracy/TestScript
xmodlog.log
tracy@tracy-HP17:/usr/lib/systemd/system-sleep$ nl /home/tracy/TestScript/xmodlog.log
     1  default
tracy@tracy-HP17:/usr/lib/systemd/system-sleep$ rm /home/tracy/TestScript/xmodlog.log
rm: remove write-protected regular file '/home/tracy/TestScript/xmodlog.log'? y
tracy@tracy-HP17:/usr/lib/systemd/system-sleep$ ls /home/tracy/TestScript

此外,下面是 journalctl 在睡眠前和恢复后显示的最后两行(按时间戳):

睡前最后两行

tracy@tracy-HP17:/usr/lib/systemd/system-sleep$ journalctl -xe | grep 'sleep\|suspend'
Mar 09 21:30:21 tracy-HP17 sudo[132552]:    tracy : TTY=pts/0 ; PWD=/usr/lib/systemd/system-sleep ; USER=root ; COMMAND=./20xmodmap
Mar 09 21:37:40 tracy-HP17 sudo[132821]:    tracy : TTY=pts/0 ; PWD=/usr/lib/systemd/system-sleep ; USER=root ; COMMAND=./20xmodmap

简历后的最后两行

tracy@tracy-HP17:/usr/lib/systemd/system-sleep$ journalctl -xe | grep 'sleep\|suspend'
Mar 09 21:30:21 tracy-HP17 sudo[132552]:    tracy : TTY=pts/0 ; PWD=/usr/lib/systemd/system-sleep ; USER=root ; COMMAND=./20xmodmap
Mar 09 21:37:40 tracy-HP17 sudo[132821]:    tracy : TTY=pts/0 ; PWD=/usr/lib/systemd/system-sleep ; USER=root ; COMMAND=./20xmodmap

看起来该脚本没有在恢复时运行,因为之前和之后的 journalctl 的输出是相同的......

编辑6:

好的,根据下面 blitzter47 的评论,我从电源管理的角度更深入地研究了这里发生的一切。看来我对发生的事情有一些(错误的)先入之见。

首先,按照注释中的提示,发出sudo systemctl suspend然后唤醒系统执行位于 中的脚本/lib/systemd/system-sleep,如正在创建的目标文件所示,其中包含单词“post”。这是第一次(除了从命令行执行脚本外)发生这种情况(我对这一进展感到非常兴奋)。

所以,这让我想知道这个命令有什么不同,以及我一直在做什么。读完这篇文章后了解暂停我认为当时的情况是,我正处于 S1 状态,但命令sudo systemctl suspend正处于 S3 状态。或者换句话说,我只是锁定了屏幕,但实际上并没有暂停计算机(除非机器长时间无人看管,我稍后会谈到这一点)。

因此,我重新考虑了我实际上想要完成的任务——即让某个键盘快捷键在系统“挂起”时继续存在。我之前曾注意到,有些情况下,当我返回计算机时,键盘快捷键会继续存在,而有些情况下则不会,但我当时并没有弄清楚这究竟是怎么回事。好吧,我现在假设,它继续存在的情况是系统只是锁定屏幕(即达到 S1 状态),但实际上并未挂起(即未达到 S3 状态)的情况。而键盘快捷键没有继续存在的情况,实际上是机器已达到可疑(S3)状态——可能是因为长时间未受干扰。

因此,最重要的是系统睡眠正确完成我尝试执行的操作(现在我真正理解了这是什么)。因此,我的下一步将是使用恢复键盘快捷键的命令实际更新来自编辑 5 的脚本(当我进入暂停(即 S3 状态)时,该脚本正常工作),然后查看是否存在键盘快捷键无法保存的情况,然后重新评估此时发生的情况。

因此,考虑到所有这些,我将标记blitzter47 的原始答案被接受,如果/当我注意到我的键盘快捷键在特定状态下无法存活时,我将发布一个新问题,(希望)更好地了解根本原因。

答案1

首先,Ubuntu 20.04 使用 systemd,而不是 pm。其次,使用 systemd 的脚本内容不同。您应该尝试使用下面的模板,并将脚本放入/lib/systemd/system-sleep/可执行位中:

#!/bin/sh

PATH=/sbin:/usr/sbin:/bin:/usr/bin

case "$1" in
    pre)
            #code execution BEFORE sleeping/hibernating/suspending
    ;;
    post)
            #code execution AFTER resuming
    ;;
esac

exit 0

PATH=/sbin:/usr/sbin:/bin:/usr/bin如果您打算像在终端命令行中一样调用命令,则需要明确指定 的行。如果没有,则必须使用相关命令二进制文件的绝对路径,例如,$ /usr/bin/touch /myfile而不是$ touch /myfile

查找命令二进制文件的绝对路径

您可以使用例如获取/检查特定命令二进制文件的绝对路径,它将输出我们感兴趣的$ whereis touch二进制文件的绝对路径:/usr/bin/touch

$ whereis touch
touch: /usr/bin/touch /usr/share/man/man1/touch.1.gz

systemd suspend.target 是否启用?

如果不起作用,您可以检查 systemd 相关目标是否已启用

$ sudo systemctl status sleep.target suspend.target hibernate.target hybrid-sleep.target

输出应如下所示:

● sleep.target - Sleep
     Loaded: loaded (/lib/systemd/system/sleep.target; static; vendor preset: enabled)
     Active: inactive (dead)
       Docs: man:systemd.special(7)

[...]

● suspend.target - Suspend
     Loaded: loaded (/lib/systemd/system/suspend.target; static; vendor preset: enabled)
     Active: inactive (dead)
       Docs: man:systemd.special(7)

[...]

● hibernate.target - Hibernate
     Loaded: loaded (/lib/systemd/system/hibernate.target; static; vendor preset: enabled)
     Active: inactive (dead)
       Docs: man:systemd.special(7)

[...]

● hybrid-sleep.target - Hybrid Suspend+Hibernate
     Loaded: loaded (/lib/systemd/system/hybrid-sleep.target; static; vendor preset: enabled)
     Active: inactive (dead)
       Docs: man:systemd.special(7)

答案2

在恢复时执行脚本的最简单方法是将可执行文件放入/etc/pm/sleep.d。这些是我在使用 Ubuntu 18.04 及更高版本时成功执行的步骤:

  1. 将脚本保存/etc/pm/sleep.d10_action_description

  2. 确保文件归 root 所有:

    sudo chown root:root /etc/pm/sleep.d/10_play_windows_xp_chimes
    
  3. 确保文件是可执行的:

    sudo chmod +x /etc/pm/sleep.d/10_play_windows_xp_chimes
    

这个过程的一个最新示例(带有工作脚本)可以在这里找到

希望这能帮助你实现你的目标

相关内容