如何编写运行systemd-tmpfiles的systemd .service文件


16

我需要systemd-tmpfiles --create在系统发行版的引导过程中运行。所以我需要创建一个systemd .service文件来完成这项工作。

在这个问题中,您可以阅读有关我需要的所有详细信息以及原因:systemd-tmpfiles如何工作?

我已经阅读了一些文档,正在编写以下测试:

[Unit]
Description=Execute tmpfiles to disable usb-wakeup # see details in the link above
Requires=multi-user.target # see details in the link above
After=multi-user.target    # see details in the link above

[Service]
Type=oneshot
ExecStart=/usr/bin/systemd-tmpfiles --create

[Install]
WantedBy=multi-user.target

但是我不确定,因为systemd-tmpfiles这不是一个简单的程序,而是一个systemd本身。我不想破坏我的系统。

有关正确的.service文件的任何提示?


freedesktop.org/wiki/Software/systemd上查看systemd上的大量文档。您可以使用自己的文件覆盖系统的默认值。
vonbrand

Answers:


30

[这不能直接解决systemd-tmpfiles的问题,但是我认为您已经认识到在这种特殊情况下,最好只使用echo。

首先,“ multi-user.target”可能不是您想要使用的。如果您熟悉SysV样式init东西中的运行级别的概念,则多用户相当于运行级别3的系统化版本,运行级别3是引导至控制台而不是GUI的多用户系统。相当于X的运行级别5是graphic.target。默认值是由称为default.target的符号链接/etc/systemd/system(和/或/lib/systemd/system;其中的一个/etc将否决一个/lib)确定的,使用ls查找它指向的位置:

»ls -l /etc/systemd/system/default.target
default.target -> /usr/lib/systemd/system/multi-user.target

对于普通的Linux桌面,这将是graphic.target。如果您要启动正在创建的引导服务而不管默认运行级别/目标是什么,那么这实际上并不重要-在这种情况下,我们可以只使用default.target,而不必担心它是什么别名。但是,如果您使用多用户,并且默认设置是图形用户,则不会发生服务。

根据服务的不同,您可能想要启动与之相关的更适当和特定的目标或服务。根据您的其他问题,default.target可能很好。需要注意的是,“目标”和“服务”之间的区别在于,服务包含[Service]实际运行流程的部分;目标只是通过各种“依赖”和“需要”指令将服务分组在一起的一种方式;除了触发其他目标或服务之外,它并不会做任何其他事情。

服务何时启动取决于其他哪些服务明确依赖于它。对于这样一个简单的独立事件,我们希望在启动过程中延迟运行,可以使用以下伪指令组合:

[Unit]
After=default.target

[Install]
WantedBy=default.target

安装服务时使用“安装”部分。“ WantedBy”指定了我们希望此服务包含在其中的目标(这意味着该目标将运行该目标,但是nb。这并不确定它何时相对于其他目标运行)。由于我们实际上希望此服务晚点而不是早点运行,因此我们指定了“ After”子句。实际上,这不必与WantedBy目标相同(通常不是这样),如果您不在乎它何时发生,可以完全省略。我只是以预感,大多数其他东西将与已链接到已指定的东西Before=default.target(我们也可以使用;目标的需求在运行目标之前进行评估)相关的东西一起运行时使用。

对于示例,我将向控制台回显“ hello world”。服务本身在以下[Service]部分中进行描述:

[Service]
Type=forking
ExecStart=/usr/local/bin/helloworld

该命令需要完整路径。我不仅仅使用/usr/bin/echo "hello world"它的原因是,它不起作用(我认为输出将输出到/ dev / null),而当一个服务执行echo "hello world" > /dev/console遗嘱时,实验表明,在ExecStart指令中使用shell重定向不会。因此/ usr / local / bin / helloworld是一个shell脚本,其中只有一行echo "hello world" > /dev/console

注意Type=forkingshell脚本所必需的。

我们完整的,最小的服务文件只是这三个部分([Unit][Service],和[Install])。要安装,请将文件或指向它的符号链接放置在/ etc / systemd / system或/ usr / lib / systemd / system中,然后:

systemctl --system enable helloworld

它应该打印ln -s ...。这不会运行该服务,它只是将其配置为在引导时运行,如上所述。

简而言之就是这样。 man systemd.unitman systemd.service有更多详细信息。


1
谢谢你,非常有用的答案和解决的问题。请注意,在我的发行版中(Chakra Linux)default.target不在中/etc/systemd/system,但仅在/usr/lib/systemd/system
13年

命令的输出已记录(可能在其他地方)?
vonbrand

/ usr / lib / systemd / ...文件是备用文件(默认),您应该将其放入/ etc / systemd / ...
vonbrand 2013年

这些天default.target可以在/lib/systemd/system/default.target
czerasz 18'Feb

1
@czerasz我在Fedora 27上注意到,如果我在中保留systemctl set-default ...一个符号链接/etc/systemd/system,但它不会更改in中的符号链接/lib,即它们指向不同的目标,但是前者中的内容应优先于后者。如果您自行设置,则可能会发生。无论如何,我在两个位置都进行了编辑。
goldilocks

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.