我有一些东西不想在图形会话运行时更新,但很乐意在关机时(图形会话结束后,网络仍然开启时)更新它们一次。所以,我不想编写服务文件,启用它,然后在每次关机时运行它。
现在,我想,好吧,systemd-run
来救援吧:
systemd-run \
--property=Type=oneshot \
--property=DefaultDependencies=no \
--property=Requires=network.service \
--property=WantedBy=shutdown.target \
/usr/bin/dnf5 update -y package1 packge2…
但这失败了
Failed to start transient service unit: Dependency type WantedBy may not be created transiently.
还有其他方法吗?
此命令基于我在 Ask Ubuntu 上回答的问题的推断和改编,我将其转换为命令
systemd-run
。推断和改编的答案有助于理解命令背后的原因,并有助于将其设置为永久服务而不是临时单元,如下所示。请注意,这将在关机时运行,而不会在重启时运行。这是故意的。如果您不希望这样,并且希望在关机和重启时都运行它,只需将属性替换
ExecStop
为dnf5 update -y package1
。package1
根据需要进行更换。我的研究告诉我:
oneshot
后立即锁定服务network-online.target
,同时将其标记为活动使用RemainAfterExit=true
,并为其提供一个ExecStop
操作,该操作将在系统关闭时(就在网络关闭之前)“自然”触发。poweroff.target
仅在系统因关机而关闭时才会处于活动状态。因此,将所有内容放在一起,可以通过创建一个服务来完成
/etc/systemd/system/update.service
(当然,文件的名称和Description
和ExecStop
字段可以调整;确保该文件归所有root:root
并具有644
/-rw-r--r--
权限):完成后,运行
sudo systemctl enable --now update.service
以启用该服务。TimeoutStopSec=infinity
在更新的情况下显然是需要的,但如果您想将其用于其他用途,可以进行更改。我已经要求@TomYan 将他们的评论转换为答案;遗憾的是,他们没有这样做,所以我的赏金将付之东流。无论如何:
这里的方法是利用单元可以具有在退出时执行的命令这一事实;因此,具有
Type=oneshot
ExecStart
(如 /usr/bin/true)(如果通过单元文件指定,则根本没有)RemainAfterExit=true
(即使虚拟对象已经退出,也将其标记为仍然有效)ExecStop=
运行我需要的命令After=network.target
确保该单元在网络停止之前停止(它指定它应该在之后启动,但在之前停止)应该可以工作,并且如果启动一次就会在关机时停止。
我注意到停止超时可能是一个问题,但它不再是一个那么严重的问题,因为从 systemd 188 开始,可以
TimeoutStopSec=
为服务进行配置。对于仅一次更新,请尝试 at-job。否则:
对于 Debian 之类的系统,安装和配置
unattended-upgrades
是必经之路。它提供了关机时安装的选项。Redhat 的对应版本是
dnf-automatic
。两者都使用 systemd-timer。
如果您不想更新特定的包,您可以固定/保留它们。