有没有办法在服务文件中动态设置服务名称?
我正在运行一个服务的多个实例,其中所有服务都使用不同的输入参数。对于调试来说,这并不是最佳选择,因为所有服务都被称为相同的,并且找出哪个服务实际上在抱怨可能很乏味。所以我想要的是为给定的输入赋予服务一个唯一的名称。 Systemds 服务文件ExecStart
通过设置前缀“@”来更改 arg[0] 来支持此功能,其中第二个参数将是 arg[0] 值。
有关ExecStart
命令和的信息@字首:
https://www.freedesktop.org/software/systemd/man/systemd.service.html
这就是我的服务文件中到目前为止的内容:
ExecStart=@/usr/bin/foo foo-%I %I
输入参数是一个文件,因此它的名称类似于 bar-123.json。当我使用 top、ps 或我们正在使用的 QA 工具时,这有效,服务名称将为 foo-bar-123.json。输入文件由另一个服务创建,该服务也使用 systemctl dbus api 启动“foo”服务实例。
然而,拥有名为 foo-bar-123.json 的服务并不是最好的,我想称之为 foo-bar。
我尝试过运行,作为测试:
**ExecStartPre=/bin/sh -c 'export NAME=bar'**
**ExecStart=@/usr/bin/foo foo-${NAME} %I**
但随后的名称将是“foo-”。我猜测这是可以预料的,因为服务文件不是 shell 脚本,但这是我能想到的唯一解决方案。
也欢迎其他问题的解决方案。我知道 prctl 函数中的 PR_SET_NAME 也应该更改进程的名称,但我不确定它们与谁相关。我不想使用 prctl 函数的原因是,名称的长度只能是 16 个字节,包括空字节,这是一个我最好不要有的限制。
答案1
通常有两种方法可以使用 systemd 服务单元实例。要么在每个实例中使用/etc/sysconfig
覆盖例如的文件。默认选项变量(EnvironmentFile
在服务定义中将加载此类文件并填充选项,参见示例systemctl show -p ExecStart sshd
)或通过“drop-in”目录覆盖更多单元定义,例如。<service>@instance.service.d
。
顺便说一句,实例必须有“@”,否则它就不是一个实例。
看看它在getty
服务单位中是如何使用的。
$ ls -l /usr/lib/systemd/system/[email protected]
-rw-r--r-- 1 root root 1958 Apr 9 00:22 /usr/lib/systemd/system/[email protected]
$ grep ^ExecStart /usr/lib/systemd/system/[email protected]
ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear %I $TERM
$ systemctl -t service --state running list-units | grep getty
[email protected] loaded active running Getty on tty1