cron 能唤醒我的电脑吗?

vas*_*lav 10 python scripts cron automation

我需要每天午夜启动一个 Python 脚本,在互联网上进行了一些搜索后,我发现我可以使用 cron 来实现它。我很好奇的是,如果我在午夜安排一个 cron 任务,它会唤醒我的计算机来完成这项工作吗?还是我必须使用其他东西唤醒计算机?我正在使用 Ubuntu 16.04。

Jac*_*ijm 13

简短的回答:

不。

但是,您可以使用rtcwake。使用rtcwake,您可以唤醒计算机,将其设置为之后运行命令和脚本等。

选项包括在绝对时间醒来,以及从现在起在特定时间范围内醒来:

-s seconds | --seconds seconds
    Sets the wakeup time to seconds in future from now. 
-t time_t | --time time_t
    Sets the wakeup time to the absolute time time_t. time_t is the time in seconds since 1970-01-01, 00:00 UTC. Use the 
Run Code Online (Sandbox Code Playgroud)

如何使用 rtcwake 的一个例子是在这个答案中
另见,一如既往,man rtcwake


Zol*_*tan 6

已经有一个答案提到您可以用于rtcwake此目的,我想详细说明您如何做到这一点。

先决条件

首先,安装rtcwake(从util-linux包中),dmidecode然后anacron

sudo apt install util-linux dmidecode anacron
Run Code Online (Sandbox Code Playgroud)

检查您的计算机是否可以从待机模式唤醒:

sudo rtcwake -m mem -s 30
Run Code Online (Sandbox Code Playgroud)

这将使您的计算机进入待机模式并在 30 秒后将其唤醒。(我选择 30 秒是因为挂起或休眠计算机可能需要一些时间,如果唤醒时间早于待机过程结束,则唤醒可能不起作用。)

您可以尝试其他待机方法memdisk特别是可以节省更多电量,但如果不手动提供密码,加密系统将无法从中恢复。

如果您的计算机成功唤醒,请检查是否可以确定唤醒原因:

sudo dmidecode | grep "Wake-up Type"
Run Code Online (Sandbox Code Playgroud)

如果您Wake-up Type: APM Timer在输出中看到,那么就可以开始了。

用于暂停的自定义脚本

如果满足所有先决条件,我们可以编写一个简单的脚本来执行以下操作:

  • 暂停计算机,同时设置唤醒时间。
  • 唤醒后,检查唤醒是计划唤醒还是手动唤醒。
  • 如果已安排唤醒,则执行 cron 作业并将计算机置于待机状态,设置新的唤醒。

这是脚本:

#! /bin/bash
# https://askubuntu.com/a/1323317
while true
do
  wake_at=22:05 # Set to whenever you want the cron jobs to run each day
  wake_ts="$(date -d "$wake_at" +%s)"
  now_ts="$(date +%s)"
  if [ "$wake_ts" -lt "$now_ts" ]
  then
    wake_ts="$(date -d "tomorrow $wake_at" +%s)"
  fi
  rtcwake -m mem -t "$wake_ts"

  # After wake-up
  #
  # Without this sleep, the current time would still seem to be the instant when
  # the suspend happened, confusing man and machine alike.
  sleep 1
  if dmidecode | grep -q "Wake-up Type: APM Timer"
  then
    # We trigger anacron manually. To prevent cron jobs from running during
    # active uptime, its systemd triggers need to be disabled.
    /usr/sbin/anacron -nd
  else
    exit 0
  fi
done
Run Code Online (Sandbox Code Playgroud)

该脚本需要以 root 身份执行,因此我建议将 root 用户设置为所有者并用于sudo启动它。您可以使用 sudoers 机制来运行它而无需输入密码,但我不会在这里详细说明,因为它已经在很多指南中进行了描述。

为了使此机制更易于使用,我建议在桌面环境中设置热键。如果这样做,您应该使用一个包装脚本来指示桌面环境特定的屏幕保护程序命令在执行上面的脚本之前锁定屏幕sudo

禁用正常时间表

如果您希望 cron 作业在计划的唤醒时间运行,而不是在计算机的活动正常运行时间内运行,则需要禁用其现有计划。在 Ubuntu 上,cron 作业组织在目录中,但这些目录由以下位置的较低级别作业执行/etc/crontab

25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
Run Code Online (Sandbox Code Playgroud)

您可以看到,仅在未安装 anacron 的情况下才会执行每日、每周和每月运行的 crontab 条目(目的是让 anacron 接管执行它们的任务)。由于我们刚刚安装了 anacron,cron 不会再自动运行这些作业,但 anacron 会,我们需要禁用它。

Anacron本身也是一个由systemd触发的计划任务。要禁用它,请发出:

sudo systemctl mask --now anacron.service
sudo systemctl mask --now anacron.timer
Run Code Online (Sandbox Code Playgroud)

我在互联网上发现了有关此问题的冲突信息,而不是mask,可能就足够了,但可能有助于防止软件包升级重新启用禁用的项目。disablemask

完成此操作后,每日、每周和每月的 cron 作业将不会在计算机的正常运行时间内执行,只能通过上面提供的挂起脚本执行,并且仅在计划的唤醒之后执行。