今天查看openvpn的systemd service文件openvpn@.service的时候,发现启动项目里配置了 --config %i.conf
# /usr/lib/systemd/system/openvpn@.service[Unit]Description=OpenVPN Robust And Highly Flexible Tunneling Application On %IAfter=network.target[Service]Type=notifyPrivateTmp=trueExecStart=/usr/sbin/openvpn --cd /etc/openvpn/ --config %i.conf[Install]WantedBy=multi-user.target
这是 systemd 模板单元(template unit)的核心设计:通过 %i 自动替换实例名称,从而用一份 openvpn@.service 文件管理所有配置文件。
为什么是 --config %i.conf?
- • 当我们执行
systemctl start openvpn@new_config 时,systemd 会将 实例名new_config 替换掉 %i,最终执行的命令是:/usr/sbin/openvpn --cd /etc/openvpn/ --config new_config.conf
- • 同理,如果启动
openvpn@any_other_name,就会自动加载 /etc/openvpn/any_other_name.conf。 - • 优势:无需为每个配置文件单独写一个 service 文件,只要配置文件放在
/etc/openvpn/ 下并以 .conf 结尾,就可以用 systemctl start openvpn@文件名(不带.conf) 来启动。
可能会问:为什么 systemctl cat 没有显示实例自己的文件?
因为 openvpn@new_config 服务 没有自定义覆盖(drop-in 文件),也没有独立的实例单元文件,所以 systemctl cat 只会显示模板文件 /usr/lib/systemd/system/openvpn@.service 的内容。这属于正常情况,说明该实例完全使用模板的默认配置。
总结
- •
%i.conf 是 systemd 模板的标准用法,让你用一条通用规则管理所有实例,非常简洁。 - • 你现在看到的就是模板本身,没有针对该实例的额外配置。
- • 如果需要个性化,用
systemctl edit 添加覆盖即可。