A.服务
[Unit]
Description = A-service
Conflicts= B.service
After = network.target
[Service]
PermissionsStartOnly = true
PIDFile = /run/AB/ab.pid
User = root
WorkingDirectory = /root/AB_services
ExecStartPre = /bin/mkdir /run/AB
ExecStartPre = /bin/chown -R root:root /run/AB
ExecStart = /usr/bin/python test_A.py --pid /run/AB/ab.pid
ExecReload = /bin/kill -s HUP $MAINPID
ExecStop = /bin/kill -s TERM $MAINPID
ExecStopPost = /bin/rm -rf /run/AB
PrivateTmp = true
[Install]
WantedBy = multi-user.target
B、服务
[Unit]
Description = B-Service
Conflicts = A.service
After = network.target
[Service]
PermissionsStartOnly = true
PIDFile = /run/AB/ab.pid
User = root
WorkingDirectory = /root/AB_services
ExecStartPre = /bin/mkdir /run/AB
ExecStartPre = /bin/chown -R root:root /run/AB
ExecStart = /usr/bin/python test_B.py --pid /run/AB/ab.pid
ExecReload = /bin/kill -s HUP $MAINPID
ExecStop = /bin/kill -s TERM $MAINPID
ExecStopPost = /bin/rm -rf /run/AB
PrivateTmp = true
[Install]
WantedBy = multi-user.target
我最初启动了,A.service
它成功启动了。但是,当我启动时B.service
,我看到正在A.service
结束。但它ExecStopPost
似乎没有执行,因为我收到以下错误:
/bin/mkdir: cannot create directory ‘/run/AB’: File exists
ExecStopPost
真的不行吗Conflicts
??
谢谢。
答案1
您尚未指定这两项服务之间的任何排序限制。因此,正在发生的事情是在完成停止(并执行)之前B.service
启动(并执行)。 的相关部分mkdir
A.service
rm
systemd.unit 文档:
Conflicts=
请注意,此设置独立于 After= 和 Before= 排序依赖关系并与之正交。
解决方案是将其他服务添加到每个服务的After=
列表中(添加到的列表A.service
中,反之亦然)。 另请参阅相关部分B.service
After=
文档:
Before=, After=
给定两台设备之间存在任何顺序相关性,如果一台设备关闭而另一台设备启动,则关闭顺序将先于启动顺序。在这种情况下,排序依赖项是 After= 还是 Before= 并不重要。关闭两者中的哪一个并不重要,只要关闭一个并启动另一个即可。在所有情况下,关闭都是在启动之前命令的。
After=
^ 意味着您是否使用或并不重要Before=
。他们都会完成同样的事情。
答案2
谢谢帕特里克对于这样一个解释性的答案并消除了我的一些疑虑。
谢谢想知道代表我进行测试。
作为帕特里克的回答提到,由于未定义的顺序,它可能会行为不当。B.service
无法运行,mkdir
因为该目录已经存在并且A.service
尚未删除。
您可以为它们定义一个顺序。无论哪个先启动,它们都会按照您当前的要求表现相同。
或者,您可以
pid
为这两个服务创建单独的文件,然后ExecStopPost
只需删除该pid
文件而不是目录。
请记住,如果您遵循第二种方法,则ExecStartPre
不需要。
仅供参考,在浏览了一些init.d
脚本之后,我认为放置pid
文件的最佳位置是/var/run/
不创建任何额外的目录。仅当您的服务以 root 身份启动时,这才有效,因为该位置仅对 root 进行写保护。