我一直在添加一些systemd服务。我从我的服务开始,符号链接来自:
/etc/systemd/system/multi-user.target.wants/myservice.service -> /home/myservice.service
这似乎工作正常。 但是如果我删除符号链接并使其成为conrete文件,则服务不会加载(systemctl daemon-reload
找不到它(。
但是,如果我将服务移动到/etc/systemd/system/myservice.service
那么它就可以正常工作。
因此,似乎要使服务在多user.target.want中工作,它需要是一个符号链接。为什么?有没有办法解决这个问题?
我之前在多用户.target.wants中看到过指向../myservice.service
的符号链接...我猜我偶然发现了原因!?
.wants/
和.requires/
目录中只允许符号链接。按照自定义,符号链接指向/etc/systemd/system/
、/usr/lib/systemd/system/
或其他单元目录中的实际单元文件。但是systemd并不太关心符号链接目标。(符号链接的目标目录将被完全忽略。检查符号链接目标的最后一个组件,如果目标名称与符号链接名称不匹配,较新的 systemd 将发出警告,但仍会接受它(。符号链接的存在表明需要创建"需要"或"需要"依赖项。
.wants/
和.requires/
目录是一种声明依赖项的机制。但是要实际加载单元,systemd 需要找到单元文件。它需要位于其中一个目录中(/etc/systemd/system/
、/usr/lib/systemd/system/
等(。
您可能会对以下事实感到困惑:较旧的 systemd 会遵循来自.wants/
或.requires/
的单元符号链接并加载单元文件。这是有问题的,原因有两个:首先是 systemd 对目录有优先级顺序,它应该在优先级最高的目录中加载单元文件。但符号链接可能指向优先级较低的目录中的单元文件。为了保持一致,systemd 必须忽略符号链接目标,并按顺序搜索目录。第二个原因是符号链接可能指向搜索路径之外的文件。如果 systemd 允许加载这些单元,则可以将这些单元作为另一个单元的依赖项加载,但是当要求直接加载单元时,systemd 将无法找到它。较新的 systemd 从不遵循此类符号链接。
上一段中的第二个原因也是为什么systemd不允许.wants/
或.requires/
中的真实文件:该单元只能作为另一个单元的依赖项加载,而不能直接加载。
有两种正确的方法可以处理此问题:
- 将单元文件移动到其中一个单元目录,例如
/etc/systemd/system/myservice.service
,并从multi-user.target.wants/
符号链接到它。 - 将单元文件保存在其他地方,例如
~/myservice.service
,并从其中一个单元目录符号链接到它,例如/etc/systemd/system/myservice.service
,并从multi-user.target.wants/
符号链接到该符号链接。
另请参阅可以为您创建这些符号链接的systemctl link
和systemctl enable
。