如何覆盖或配置systemd服务?
许多sysv init脚本使用/etc/default
的相应文件来允许管理员对其进行配置。 可以使用.override
文件修改Upstart作业。 现在systemd是Ubuntu中的默认设置,如何覆盖或配置systemd单元?
systemd
单元不需要服从/etc/default
文件。 systemd
很容易配置,但要求您知道systemd单元文件的语法。
软件包通常在/lib/systemd/system/
单元文件。 这些不需要编辑。 相反, systemd
允许您通过在/etc/systemd/system/
创建适当的文件来覆盖这些文件。
对于给定的服务foo
,该包将提供/lib/systemd/system/foo.service
。 您可以使用systemctl status foo
检查其状态,或使用journalctl -u foo
查看其日志。 要覆盖foo
定义中的某些内容,请执行以下操作:
sudo systemctl edit foo
这将在/etc/systemd/system
创建一个以该单元命名的目录,以及该目录中的override.conf
文件( /etc/systemd/system/foo.service.d/override.conf
)。 您可以使用此文件(或/etc/systemd/system/foo.service.d/
其他.conf
文件)添加或覆盖设置。
覆盖命令参数
以getty
服务为例。 假设我想为我的用户提供TTY2自动登录(这不是建议,但只是一个例子)。 TTY2由getty@tty2
服务运行( tty2
是模板/lib/systemd/system/getty@service
的实例)。 为此,我必须修改getty@tty2
服务。
$ systemctl cat getty@tty2 # /lib/systemd/system/getty@.service # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. [Unit] Description=Getty on %I Documentation=man:agetty(8) man:systemd-getty-generator(8) Documentation=http://0pointer.de/blog/projects/serial-console.html After=systemd-user-sessions.service plymouth-quit-wait.service After=rc-local.service # If additional gettys are spawned during boot then we should make # sure that this is synchronized before getty.target, even though # getty.target didn't actually pull it in. Before=getty.target IgnoreOnIsolate=yes # On systems without virtual consoles, don't start any getty. Note # that serial gettys are covered by serial-getty@.service, not this # unit. ConditionPathExists=/dev/tty0 [Service] # the VT is cleared by TTYVTDisallocate ExecStart=-/sbin/agetty --noclear %I $TERM Type=idle Restart=always RestartSec=0 UtmpIdentifier=%I TTYPath=/dev/%I TTYReset=yes TTYVHangup=yes TTYVTDisallocate=yes KillMode=process IgnoreSIGPIPE=no SendSIGHUP=yes # Unset locale for the console getty since the console has problems # displaying some internationalized messages. Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION= [Install] WantedBy=getty.target DefaultInstance=tty1
特别是,我必须更改ExecStart
行,目前是:
$ systemctl cat getty@tty2 | grep Exec ExecStart=-/sbin/agetty --noclear %I $TERM
要覆盖它,请执行:
sudo systemctl edit getty@tty2
并添加:
[Service] ExecStart= ExecStart=-/sbin/agetty -a muru --noclear %I $TERM
注意:
- 我必须在再次设置之前明确地清除
ExecStart
,因为它是一个附加设置,类似于After
,Environment
(作为一个整体,而不是每个变量)和EnvironmentFile
,并且反对重写设置,如RestartSec
或Type
。ExecStart
只能为Type=oneshot
服务提供多个条目。 - 我不得不使用正确的节头。 在原始文件中,
ExecStart
位于[Service]
部分,因此我的覆盖也必须将ExecStart
放入[Service]
部分。 通常,使用systemctl cat
查看实际的服务文件会告诉您需要覆盖的内容以及它所在的部分。
通常,如果编辑systemd单元文件,要使其生效,则需要运行:
sudo systemctl daemon-reload
但是, systemctl edit
自动为您执行此操作。
现在:
$ systemctl cat getty@tty2 | grep Exec ExecStart=-/sbin/agetty --noclear %I $TERM ExecStart= ExecStart=-/sbin/agetty -a muru --noclear %I $TERM $ systemctl show getty@tty2 | grep ExecS ExecStart={ path=/sbin/agetty ; argv[]=/sbin/agetty -a muru --noclear %I $TERM ; ... }
如果我这样做:
sudo systemctl restart getty@tty2
并按Ctrl Alt F2 ,presto! 我将在该TTY上登录我的帐户。
正如我之前所说, getty@tty2
是模板的一个实例。 那么,如果我想覆盖该模板的所有实例呢? 这可以通过编辑模板本身来完成(删除实例标识符 – 在本例中为tty2
):
systemctl edit getty@
压倒环境
/etc/default
文件的常见用例是设置环境变量。 通常, /etc/default
是一个shell脚本,因此您可以在其中使用shell语言结构。 但是,对于systemd
,情况并非如此。 您可以通过两种方式指定环境变量:
通过文件
假设您已在文件中设置环境变量:
$ cat /path/to/some/file FOO=bar
然后,您可以添加到覆盖:
[Service] EnvironmentFile=/path/to/some/file
特别是,如果/etc/default/grub
仅包含赋值而没有shell语法,则可以将其用作EnvironmentFile
。
通过Environment
条目
以上也可以使用以下覆盖来完成:
[Service] Environment=FOO=bar
但是,对于多个变量,空格等,这可能会变得棘手。请查看我的其他答案之一,了解此类实例的示例。
进一步阅读
通过这种机制,可以很容易地覆盖systemd
单元,以及撤消这些更改(通过简单地删除覆盖文件)。 这些不是唯一可以修改的设置。
以下链接很有用:
- 在
systemd
上的Arch Wiki条目 - systemd for Administrators ,第IX部分:在/ etc / sysconfig和/ etc / default上 (由systemd的主要开发者,Lennart Poettering)
-
systemd
manpages ,特别是systemd.unit
和systemd.service
的联机帮助systemd.service
- 用于Upstart用户的Systemd上的Ubuntu Wiki条目