我发现systemd-run
它允许人们一次性在后台运行进程(“临时服务”)。我总是用 指定服务单元名称--unit $NAME
。但如果我已经运行了命令systemd-run
并且我的进程正在运行,那么systemd-run
将失败,并返回非零退出代码。有没有办法告诉systemd-run
它更具幂等性并且在这种情况下不会失败?
目前我正在做的事情:
systemctl is-active $NAME || systemd-run --unit $NAME $COMMAND
有没有更好的办法?
这是在 Ubuntu 18.04 上,使用当前的 systemd(版本 237?)
答案1
-G,--收集
临时单元完成后,即使失败,也会将其卸载。通常,如果没有此选项,所有运行并失败的单元都会保留在内存中,直到用户使用 systemctl reset-failed 或等效命令明确重置其故障状态。另一方面,成功运行的单元会立即卸载。如果启用此选项,单元的“垃圾收集”会更积极,无论单元退出成功还是失败,都会卸载它们。此选项是 --property=CollectMode=inactive-or-failed 的快捷方式,有关更多信息,请参阅 systemd.unit(5) 中 CollectMode= 的说明。
systemd-run --collect --unit $NAME $COMMAND
答案2
我认为没有不失败的方法。
这里的问题是 systemd 单元名称必须是唯一的。如果不是,那么操作单元可能会变得模糊。因此,如果您尝试重复单元名称,systemd 会认为这是一个错误,我认为没有办法让它认为不是这样。
如果您可以systemd-run
运行同名的第二个服务,那么发出systemctl stop
命令会发生什么?两个同名单元中的哪一个应该停止?您首先运行的那个?最后一个?还是两个?
答案3
你会需要--collect
删除该单元(参见答案https://serverfault.com/a/1056478/161855)。
$ systemctl is-active foo || systemd-run --collect --unit foo sleep 1000
inactive
Running as unit: foo.service
$ systemctl is-active foo || systemd-run --collect --unit foo sleep 1000
active
这引入了轻微的托克托systemd-run
,但总比没有好,并且如果设备已经在运行,不会导致打印错误。