服务模板
Linux/Unix上的大多数服务都是单例服务:在一个特定的系统上,通常只有一个Syslog、Postfix或Apache实例同时运行。 但是有些服务会运行多个,常见的getty@.service
,会为每个终端都运行一个,以显示登录提示,通常在tty1-tty6上运行。 还有常见的 systemd-fsck@.service
,它是一个文件系统检查器,为每个需要检查的块设备实例化一次。
systemd中的服务时根据模式名命名的,如foobar.service
,foobar是服务的标识字符串,模式支持扩展,如 foobar@quux.service
,表示在quux上运行一个foobar服务,即实例化。例如:serial-getty@ttyS2.service是 为ttyS2实例化的串行getty服务。这种方式,不需要额外配置,就可以快速创建或运行一个新的服务。
1
# systemctl start serial-getty@ttyUSB0.service
运行以上命令后,systemd将优先根据该service的具体名称查找对应的单元配置文件。如果存在,就使用对应的具体的service 文件启动服务,(即支持写明特定的实例化对象,以进行模板的override)。如果不存在,则会套用模板serial-getty@.service
, 该模板对所有示例都是通用的,大致内容如下:
1
2
3
4
5
6
7
8
9
[Unit]
Description=Serial Getty on %I
BindTo=dev-%i.device
After=dev-%i.device systemd-user-sessions.service
[Service]
ExecStart=-/sbin/agetty -s %I 115200,38400,9600
Restart=always
RestartSec=0
这相当于是一个简化版的getty@.service
,这种模板服务和普通服务基本相同,主要是它多了 %i
和 %I
, %i
和%I
会被systemd替换为服务的实例标识符。在上例中,就会被替换为ttyUSB0,查看验证:
1
2
3
4
5
6
7
$ systemctl status serial-getty@ttyUSB0.service
serial-getty@ttyUSB0.service - Getty on ttyUSB0
Loaded: loaded (/lib/systemd/system/serial-getty@.service; static)
Active: active (running) since Mon, 26 Sep 2011 04:20:44 +0200; 2s ago
Main PID: 5443 (agetty)
CGroup: name=systemd:/system/getty@.service/ttyUSB0
└ 5443 /sbin/agetty -s ttyUSB0 115200,38400,9600
这就是systemd的模板化服务的核心思想,可以使用 systemctl enable
创建 .wants 中的软链接,实现实例化 的服务的自启动。
对于模板化的服务,是一定要指定一个实例名才可以创建服务,本身的服务是不能直接创建的,因为没有实例名。
%i 和 %I 的区别
%i 后面一般跟一个确切的名称,不带路径,没有转义。 %I 可以用在在路径的名称,会对 /
进行转义
另外,还有其他特殊字符,具体参考手册。man systemd.unit