相同 systemd 服务模板的互斥实例

DrY*_*Yak 6 systemd services

如果有更好的方法来执行相同 systemd 服务模板的互斥实例,我很感兴趣。

上下文:我正在使用 SSH 隧道在我的笔记本电脑和我旁边的工作站之间协同连接。显然,只有一个隧道应该同时运行。如果打开新隧道,则应事先关闭任何仍在运行的旧隧道实例。

(这与该用户使用 VPN 服务模板实例的用例类型有很大关系)

不知何故,Conflicts=template@.service规则似乎对我没有帮助,即使 systemd 正确地从冲突列表中删除了当前实例(template@foo.service自动从自身Conflicts=列表中删除template@foo.service),它似乎也没有达到预期的结果(template@bar.service不是自动开始前停止template@foo.service)。

目前,它使用这个可怕的装置对我有用:

ExecStartPre=-/bin/sh -c 'systemctl --user stop  $$(systemctl --user list-units %p@\'*\'.service|gawk \'($$3~/^activ/)&&(!($$1~/%I/)){print $$1};\')'
ExecStart=/usr/bin/autossh -M 11111 -N -L24800:localhost:24800 %I
Run Code Online (Sandbox Code Playgroud)

这用于list-units获取此服务 remplate 的所有实例的列表(将返回template@bar.service, template@foo.service),并使用 gawk 过滤那些活动的和不是当前的实例,并且只停止那些实例(因此启动template@bar.servicetemplate@foo.service在启动之前停止)。

它对我有用,但它很丑陋,而且我确信有一种“更系统化的方式”来做到这一点,我只是不知道怎么做。