最近有人向我指出,存在 cron 的替代方案,即 systemd 计时器。
但是,我对 systemd 或 systemd 计时器一无所知。我只用过cron。
有一点Arch Wiki 中的讨论。然而,我正在寻找cron
和 systemd 计时器之间的详细比较,重点关注其优缺点。我使用 Debian,但我想对可使用这两种替代方案的所有系统进行一般比较。该集可能仅包括 Linux 发行版。
这是我所知道的。
Cron 已经很老了,可以追溯到 20 世纪 70 年代末。 cron 的原作者是 Unix 的创建者 Ken Thompson。现代 Linux 发行版中的 cron 是 Vixie cron 的直接后代,其历史可以追溯到 1987 年。
Systemd 较新,并且有些争议。维基百科告诉我它的首次发布日期是 2010 年 3 月 30 日。
因此,我目前列出的 cron 相对于 systemd 计时器的优点是:
Cron 保证存在于任何类 Unix 系统中,从某种意义上说,它是一个可安装的受支持的软件。这不会改变。相比之下,systemd 将来可能会也可能不会保留在 Linux 发行版中。它主要是一个init系统,并且可能被不同的init系统替换。
Cron 使用起来很简单。绝对比 systemd 计时器简单。
systemd 定时器相对于 cron 的相应优势列表是:
- Systemd 计时器可能更灵活、更强大。但我想要一些例子。
因此,总而言之,在答案中最好看到以下一些内容:
- cron 与 systemd 计时器的详细比较,包括使用每个计时器的优缺点。
- 一个人可以做而另一个人不能做的事情的例子。
- 至少对 cron 脚本与 systemd 计时器脚本进行并排比较。
答案1
以下是关于这两个的一些要点:
检查你的 cron 作业到底做了什么可能会有点混乱,但所有 systemd 计时器事件都会像其他基于事件的 systemd 单元一样仔细记录在 systemd 日志中,这使事情变得更加容易。
systemd 计时器是 systemd 服务,具有资源管理、IO CPU 调度等所有功能……
有一个列表:- 系统调用过滤器
- 用户/组 ID
- 会员控制
- 物有所值
- OOM 分数
- IO调度类别和优先级
- CPU调度策略CPU
- 亲和掩码
- 定时器休闲裤
- 安全位
- 网络访问和...
- 系统调用过滤器
使用依赖项选项就像其他 systemd 服务一样,可以依赖于激活时间。
单元可以通过不同的方式激活,也可以配置它们的组合。服务可以由不同的事件启动和触发,例如用户、启动、硬件状态更改,或者例如插入某些硬件后 5 分钟,...
更容易配置一些文件和直接标签,以便根据您的需要使用 systemd 计时器进行各种自定义。
通过以下方式轻松启用/禁用整个功能:
systemctl enable/disable
并杀死所有工作的孩子:
systemctl start/stop
systemd 计时器可以使用日历和单调时间来安排,这在时区不同的情况下非常有用,...
systemd 时间事件(日历)比 cron 更准确(似乎是 1 秒精度)
systemd 时间事件更有意义,对于那些重复出现的事件,甚至那些应该发生一次的事件,这里是一个来自 文档:
Sat,Thu,Mon-Wed,Sat-Sun → Mon-Thu,Sat,Sun *-*-*00:00:00 Mon,Sun 12-*-* 2,1:23 → Mon,Sun 2012-*-* 01,02:23:00 Wed *-1 → Wed *-*-01 00:00:00 Wed-Wed,Wed *-1 → Wed *-*-01 00:00:00 Wed, 17:48 → Wed *-*-* 17:48:00
从 CPU 使用率的角度来看,systemd 计时器会在经过的时间后唤醒 CPU,但 cron 这样做的频率更高。
可以根据执行的完成时间来安排计时器事件,并且可以在执行之间设置一些延迟。
与其他程序的通信也值得注意,有时其他一些程序需要了解计时器及其任务的状态。
答案2
直接从马嘴里说出来:https://wiki.archlinux.org/index.php/Systemd/Timers#As_a_cron_replacement
上面页面的摘录:
好处
使用计时器的主要好处来自于每个作业都有自己的 systemd 服务。其中一些好处是:
- 作业可以独立于其计时器轻松启动。这简化了调试。
- 每个作业都可以配置为在特定环境中运行(请参阅 systemd.exec(5))。
- 作业可以附加到 cgroup。
- 可以将作业设置为依赖于其他 systemd 单元。
- 作业记录在 systemd 日志中以便于调试。
注意事项
有些事情用 cron 很容易做到,但单独用定时器单元却很难做到。
- 复杂性:要使用 systemd 设置定时作业,您需要创建两个文件并运行几个 systemctl 命令。将其与向 crontab 添加一行进行比较。
- 电子邮件:没有与 cron 的 MAILTO 等效的内置功能,用于在作业失败时发送电子邮件。请参阅下一节,了解使用 OnFailure= 设置等效项的示例。
答案3
让我拿起您最近提到的 POP3 示例在评论中。这是一个很好的例子,因为 POP3 无法通知新邮件的到达。 (对于 IMAP 访问,我会不是使用计时器解决方案,因为 IMAP 实际上能通知!)
克朗
crontab -e
-e
代表编辑。注意:不带选项启动不会提供帮助,但如果您无法在不保存的情况下退出编辑器,则会刷新所有现有的 cron 作业。 — 如果您有现有作业,这绝对意味着会丢失工作。
所以,在编辑模式下,添加一行:
30 14,21 * * * mpop --quiet
mpop
下午 2:30 和晚上 9:30推出。
理论上你也可以编辑/var/spool/cron/crontabs/username
,但大多数 crons 不会注意到和目录权限通常不允许直接访问文件。
Cron 作业的调试乐趣较少。通常情况下,您最终会每分钟安排一次,直到您信任它并正确设置频率。
否则,它是一个用于重复工作的非常快速的界面。
如今,当您没有运行 cron 守护程序时,请不要感到惊讶。软件包systemd-cron
(至少在 Debian 上)为您提供带有 cron 用户界面的 systemd 计时器:它为您透明地转换 crontab 行,并且命令行工具是相同的。—相反的方式可能永远不会存在。
系统定时器
loginctl enable-linger
必须运行一次(并且不再运行)。它确保用户模式 systemd 在启动时启动。否则第一次登录就会启动它。
systemctl --user edit --full --force mpop.service
您还可以运行systemctl edit mpop.service
以获得连续的错误和提示,引导您使用选项进入正确的命令行:
No files found for mpop.service.
Run 'systemctl edit --force --full mpop.service' to create a new unit.
运行建议的命令将揭示写入文件的权限问题,并要求输入密码来重新加载系统守护程序。-此时,您应该记住添加--user
与用户 systemd 实例的对话。注意:您也可以选择系统实例,但我不会在这里描述它。这是相似的。
与 cron 不同,您确实可以直接访问该文件~/.config/systemd/user/mpop.service
,但您必须自己记住路径。并且在某些情况下systemd --user daemon-reload
是需要的。例如,如果文件确实存在和已加载。systemd --user edit ...
在任何情况下都会执行守护进程重新加载,因此您不必这样做。
因此,在mpop.service
文件中添加:
[Service]
Type=oneshot
ExecStart=mpop --quiet
您可以使用 来测试运行它systemctl --user start mpop
。mpop
是mpop.service
这里的缩写。
使用(的缩写)检查详细信息systemctl --user status mpop
或过去运行的完整输出。journalctl --user -u mpop
-u
--unit
对于systemd,定时器是触发服务单元的另一个单元。
创建一个:
systemctl --user edit --full --force mpop.timer
并在编辑器中保存以下内容:
[Timer]
OnCalendar=*-*-* 14,21:30:00
[Install]
WantedBy=timers.target
可以OnCalendar=
写得更短一些。由于Unit=
没有明确写入 to activate ,因此将使用同名的服务。
与服务(短期)一样,计时器(长期)最初将关闭。该服务是由定时器激活的,所以不用担心。
但是什么会激活计时器呢?——这就是该[Install]
部分发挥作用的地方。与命令有关systemctl --user enable/disable ...
。不幸的是,两者都有不好的名字。
在我看来,实际情况并非如此,应该调用该部分[Hooks]
和命令... hook/unhook ...
。理由:
- 计时器已随
mpop.timer
文件的存在而安装 - 将揭示该部分和命令之间的关系
- 该
enable
命令可能不会使能够如果该单元连接到壁板单元或不存在的壁板单元(尽管您会收到后者的警告),但它将显示为“已启用”。 - 该
mpop.service
单元没有任何[Install]
部分并且enable/disable
不执行任何操作,它显示为“静态”,即使它已“启用”
话虽如此,您可以看到该WantedBy=
钩子提到了一个众所周知的目标,该目标在正常情况下启动,并且应该用于计时器。
现在和执行以下步骤后使用systemctl --user list-dependencies default.target
,看看周围会发生什么timers.target
:
systemctl --user enable mpop.timer # hooks it into the timers.target
systemctl --user start timers.target # this or reboot
我考虑执行start
而timers.target
不是mpop.timer
更好的实践(两者都有效)。它有助于检测计时器单元部分中的拼写错误[Install]
,并更接近重新启动的执行路径。
答案4
“systemd 计时器”与“cron”就像“systemd”与“SysV init”。
您知道围绕 systemd 的无休止的争论吗?通常非常主观、非常情绪化。大多数支持和反对的论点,无论有效与否,都可以在这里几乎逐字重复。包括技术方面和乍一看是技术方面的方面。
我记得那些日子,系统用户无法启动守护进程,除非通过 cron:一个脚本,每分钟运行一次,99.9% 不执行任何操作,只是启动一个长时间运行的进程,以防机器重新启动。
如今,更多的是一个问题哪个您运行 cron 来确定我刚才描述的用例的覆盖程度(即@reboot计时器)。 (或者例如运行错过的工作的能力......)
即使没有计时器,Systemd 也能满足您的需求! –你的用例也可能最好既不使用 cron 也不使用计时器来解决。你的用例可能最好通过系统提供的钩子来解决。
更新:OP 添加了 POP3 示例。—现在我可以回答这个问题了。