我读到有两个用于单位文件的文件夹(不在用户模式下)。
/usr/lib/systemd/system/: units provided by installed packages
/etc/systemd/system/: units installed by the system administrator

与这种理解相冲突的是这个问题的答案:如何为Systemd编写启动脚本。有人可以填写缺少的信息,以便我了解发生了什么吗? (更新:答案已更新,我的理解不再与之冲突。)
此外,脚本似乎组织在/etc/systemd/system/文件夹内的子文件夹中:
getty.target.wants
multi-user.target.wants

在另一个文件夹中位置我读到还有其他位置。看来这些是针对特定用户的服务。
/usr/lib/systemd/user/ where services provided by installed packages go.
/etc/systemd/user/ where system-wide user services are placed by the system administrator.
~/.config/systemd/user/ where the user puts its own services.


更新2015-08-31:
为了其他人,这是我最近遇到的一个相关问题的链接问:我应该把由systemd单元执行的脚本放在哪里?

评论

/ etc / systemd / system是放置脚本的位置,pacman将包脚本放置在/ usr / lib / systemd / system中,然后发出systemctl enable foo.service创建从/ usr到/ etc的符号链接。

请参见man systemd.target:它解释了分组背后的原因。

#1 楼

放置系统单元文件的最佳位置:/etc/systemd/system
请务必在[安装]部分下添加目标,阅读“如何知道?”有关详细信息。更新:/usr/local/lib/systemd/system是另一个选项,请阅读“灰色区域”以获取详细信息。“
放置用户单位文件的最佳位置:/etc/systemd/user$HOME/.config/systemd/user
,但这取决于权限和情况。
事实是,系统化的单元(或序言中称其为“单元配置”)可以在任何地方使用-只要您愿意进行手动符号链接并且意识到了警告,则可以更轻松地将单元放置在systemctl daemon-reload可以找到它的原因如下:

使用标准位置意味着systemd生成器将找到它们并使其易于在systemctl enable启动时启用,这是因为您的单元将自动添加到单元依赖项中树(单位缓存)。
您无需考虑权限,因为只有适当的特权用户才可以写入指定的区域。

它怎么知道的?
systemctl enable究竟如何知道在哪里创建符号链接,请在q431下的
单元内对其进行硬编码2079q部分。通常,有一行类似于
[Install]
WantedBy = multi-user.target

的行,它对应于文件系统上的预定义位置。
这样,[install]知道此单元依赖于称为systemctl的一组单元文件(“ target”是用于指定单元依赖性组的术语。您可以使用multi-user.target列出所有组)。要装载目标的单元文件组放在systemctl list-units --type target目录中。这只是一个充满符号链接(或真实内容)的目录。如果您的targetname.target.wants部分说的是[Install]WantedBy,但是如果multi-user.target目录中不存在指向它的符号链接,则它将不会加载。当systemd单元生成器在引导时将单元文件添加到依赖关系树缓存中时(您可以使用multi-user.target.wants手动触发生成器),它会自动知道将符号链接放在何处-在这种情况下,应在目录systemctl daemon-reload中启用它。
《手册》中的要点:

其他单元可能会从
目录(不在单元加载路径上)加载到systemd(“链接”)中。请参见
systemctl(1)的链接命令。

在systemctl下,查找单元文件命令
单元文件加载路径
请阅读并理解其中的第一句话。以下来自/etc/systemd/system/multi-user.target.wants/的引号(因为这意味着如果您的systemd是用不同的路径编译的,则此处提到的所有路径可能不适用于您):

从确定的一组路径中加载单元文件在编译过程中,如下两张表所述。在较早列出的目录中找到的单位文件将覆盖列表较低目录中具有相同名称的文件。


设置变量man systemd.unit时,此变量的内容将覆盖单位装入路径。如果$SYSTEMD_UNIT_PATH以空组件(“:”)结尾,则通常的单位加载路径将附加到变量的内容中。

$SYSTEMD_UNIT_PATH的表1和表2很好。
在系统模式下运行时的加载路径(man systemd.unit)。


--system本地配置

/etc/systemd/system运行时间单位

/run/systemd/system已安装软件包的单位(在某些情况下为/usr/lib/systemd/system,请阅读/lib/systemd/system

在用户模式下运行时的加载路径(man systemd.unit
每个用户单位与所有/全局用户之间存在差异
用户相关


--user用户配置(仅在设置了$XDG_CONFIG_HOME/systemd/user时使用)


$XDG_CONFIG_HOME用户配置(仅用于当未设置$HOME/.config/systemd/user时)


$XDG_CONFIG_HOME运行时单位(仅在设置$XDG_RUNTIME_DIR/systemd/user时使用)


$XDG_RUNTIME_DIR已安装在其中的软件包单位主目录(仅在设置$XDG_DATA_HOME/systemd/user时使用)


$XDG_DATA_HOME在主目录中已安装的软件包单元(仅在未设置$HOME/.local/share/systemd/user时使用)



$XDG_DATA_HOME(所有用户)
适用于所有用户的单位-也意味着每个用户拥有的单位。因此,即使管理员在引导时启用了这些服务,每个用户都可以停止这些服务。


所有用户的本地配置(--global

/etc/systemd/user软件包的单位已为所有用户在系统范围内安装(某些情况下为systemctl --global enable userunit.service,请阅读man systemd.unit)。

/usr/lib/systemd/user运行时单元

灰色区域
另一方面,文件层次结构标准指定/lib/systemd/system用于不执行二进制文件的本地配置。另一方面,
指定/run/systemd/user“供本地安装软件时的系统管理员使用”。您还可以争辩(如果不仅仅是为了组织目的),所有系统单元文件都应放在/etc下,但这是针对属于“软件”而不是来自程序包管理器的单元文件的。
系统范围内的systemd用户单元可能位于
/usr/local/下。
瞬态单元
另一个被遗忘的地方根本没有!也许鲜为人知的程序是/usr/local/lib/systemd/system。您可以使用它来运行瞬态单元。请参阅/usr/local/lib/systemd/user
例如,要安排明天早晨在凌晨4点重新启动(您可能需要systemd-run以确保重新启动发生):
systemd-run -u restart --description="Restarts machine" --on-calendar="2020-12-18 00:04:00" systemctl --force reboot

这将产生一个临时单元文件man systemd-run和一个相应的计时器(因为--forcerestart.service指示。
--on-calendar
# This is a transient unit file, created programmatically via the systemd API. Do not edit.
[Unit]
Description=Restarts machine

[Service]
ExecStart=
ExecStart="/usr/bin/systemctl" "--force" "reboot"

请注意,还有另一个更危险的双力选项transient=yes,它告诉内核立即停止(并且,如果您不安全地不知道自己在做什么,因为这几乎等同于切断电源。

评论


关于将单位文件放在/ etc / systemd / system中的建议,这是关于自行创建的单位文件的一般建议吗?软件包管理器安装的所有内容都应始终将其放在/ usr / lib / systemd / system中,例如。

–slm♦
18年8月6日在20:25

@slm是的,当问题涉及到我的systemd单位文件时,它意在暗示着自己创建的文件。

–乔纳森·科玛(Jonathan Komar)
18-09-6在19:44



我要区分:/ etc / systemd / user(用于保证系统范围的用户服务)和〜/ .config / systemd / user(用于定制用户特定的服务)。

– Suuuehgi
19年5月17日在21:26

@JonathanKomar每次提及/ usr / lib / systemd / system时,都应在帖子中添加/ lib / systemd / system。在许多系统上(尤其是在Ubuntu上),这是正确的位置。

–Â Atralb
20年7月9日在9:36

啊,我只是以为我已经改进了一个建议使用systemctl --force reboot的编辑,然后才看到警告注意危险的评论。我将看看是否可以找到这些风险的参考。编辑:啊,警告是关于--force两次使用,我不小心将其删除了。好。

– dhag
20/12/17在16:41



#2 楼

/etc/systemd/system是放置脚本的位置,而pacman则将软件包脚本放置在/usr/lib/systemd/system中。

发出systemctl enable foo.service会创建从/usr/etc的符号链接。有关更多详细信息,请参见man systemd.unit(5)的“单位负载路径”部分。

#3 楼

我写了3个,一个写给ntpd,一个写给第二张静态以太网卡,另一个写给运行p0f的被动OS标识符。我把它们全部放在/etc/systemd/system中。看起来我可以让systemd处理NTP内容,但我认为我不想过分依赖它。

#4 楼

在Debian / Ubuntu系统上,/ etc / systemd / system和/ lib / systemd / system之间的一个明显区别是,/ lib / systemd / system下的服务文件可以被屏蔽,而/ etc / systemd / system下的服务文件则不能。例如,
# ls /lib/systemd/system/mytest.service
# systemctl mask mytest
# ls /etc/systemd/system/mytest2.service
# systemctl mask mytest2
Failed to mask unit: File /etc/systemd/system/mytest2.service already exists.