我需要每天午夜启动一个 Python 脚本,在网上搜索后,我发现可以使用 cron 来实现。我好奇的是,如果我在午夜安排一个 cron 任务,它会唤醒我的电脑来执行这项工作吗?还是我必须使用其他东西唤醒电脑?我使用的是 Ubuntu 16.04。
答案1
简短回答:
不。
你能但是使用唤醒。使用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
rtcwake 的使用示例如下:这个答案.
另请参阅,一如既往,man rtcwake
答案2
已经有一个答案提到你可以用它rtcwake
来达到这个目的,我想进一步阐述一下如何你能行的。
先决条件
首先,安装rtcwake
(从util-linux
包中),dmidecode
然后anacron
:
sudo apt install util-linux dmidecode anacron
检查您的计算机是否可以从待机模式唤醒:
sudo rtcwake -m mem -s 30
这应该会使您的计算机进入待机模式,并在 30 秒后将其唤醒。(我选择 30 秒是因为暂停或休眠计算机可能需要一些时间,并且如果唤醒时间早于待机过程的结束时间,则唤醒可能不起作用。)
您可以尝试除 之外的其他待机方法mem
,disk
特别是可以节省更多电量,但如果不手动提供密码,加密系统将无法从中恢复。
如果您的计算机成功唤醒,请检查是否可以确定唤醒的原因:
sudo dmidecode | grep "Wake-up Type"
如果您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
此脚本需要以 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 )
您可以看到,运行每日、每周和每月作业的 crontab 条目仅在未安装 anacron 时执行(否则 anacron 将接管执行这些作业的任务)。由于我们刚刚安装了 anacron,cron 将不再自动运行这些作业,但 anacron 会运行,我们需要禁用它。
Anacron 本身也是由 systemd 触发的计划任务。要禁用它,请发出:
sudo systemctl mask --now anacron.service
sudo systemctl mask --now anacron.timer
可能mask
就disable
足够了,我在网上找到了关于此问题的相互矛盾的信息,但是mask
可能帮助防止包升级重新启用已禁用的项目。
完成此操作后,每日、每周和每月的 cron 作业将不会在计算机正常运行时间内执行,仅由上面提供的挂起脚本在预定的唤醒后执行。