/etc/default
中使用了相应的文件,以允许管理员对其进行配置。可以使用.override
文件修改Upstart作业。现在,systemd是Ubuntu中的默认设置,我该如何覆盖或配置systemd单元?#1 楼
systemd
单元不必遵守/etc/default
中的文件。 systemd
易于配置,但是要求您知道systemd单位文件的语法。打包通常在
/lib/systemd/system/
中打包单位文件。这些将不被编辑。相反,systemd
允许您通过在/etc/systemd/system/
中创建适当的文件来覆盖这些文件。您可以使用foo
检查其状态,或使用/lib/systemd/system/foo.service
查看其日志。要覆盖systemctl status foo
定义中的内容,请执行以下操作:sudo systemctl edit foo
这将在
journalctl -u foo
中创建一个以该单位命名的目录,并在该目录中创建一个foo
文件(/etc/systemd/system
)。您可以使用此文件(或override.conf
中的其他/etc/systemd/system/foo.service.d/override.conf
文件)添加或覆盖设置。覆盖命令参数
以
.conf
服务为例。假设我想让TTY2自动登录到我的用户(不建议这样做,这只是一个例子)。 TTY2由/etc/systemd/system/foo.service.d/
服务运行(getty
是模板getty@tty2
的实例)。为此,我必须修改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
特别地,我必须更改
/lib/systemd/system/getty@service
行,该行当前是:$ 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
注意:
我必须先明确清除
getty@tty2
,然后再进行设置,因为它是一个加法设置,类似于ExecStart
,ExecStart
(整体而言,不是每个变量)和After
,并且与诸如Environment
之类的替代设置相反或EnvironmentFile
。 RestartSec
只能对Type
服务具有多个条目。我必须使用适当的节头。在原始文件中,
ExecStart
位于Type=oneshot
部分,因此我的替代项也必须将ExecStart
放入[Service]
部分。通常,使用ExecStart
查看实际的服务文件会告诉您需要覆盖的内容以及它所在的部分。通常,如果您编辑systemd单位文件,该文件将生效,您需要运行:
sudo systemctl daemon-reload
但是,
[Service]
会自动为您执行此操作。现在:
$ 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 ; ... }
如果我这样做了:我将在该TTY上登录我的帐户。
如前所述,
systemctl cat
是模板的实例。那么,如果我想覆盖该模板的所有实例怎么办?可以通过编辑模板本身(删除实例标识符-在这种情况下为systemctl edit
)来完成:sudo systemctl restart getty@tty2
覆盖环境
A
getty@tty2
文件的常见用例是设置环境变量。通常,tty2
是一个Shell脚本,因此您可以在其中使用Shell语言构造。对于/etc/default
,情况并非如此。您可以通过两种方式指定环境变量:通过文件
假设您已在文件中设置了环境变量:
systemctl edit getty@
然后,您可以添加到覆盖:
$ cat /path/to/some/file
FOO=bar
尤其是,如果您的
/etc/default
仅包含赋值而没有shell语法,则可以使用它如systemd
一样。通过
/etc/default/grub
条目也可以使用以下替代来完成上述操作:
[Service]
EnvironmentFile=/path/to/some/file
但是,使用多个变量,空格等会变得很棘手。请查看我的其他答案之一,以了解此类实例。通过这种机制,覆盖
EnvironmentFile
单位以及撤消此类更改(只需删除覆盖文件)变得非常容易。这些不是唯一可以修改的设置。以下链接将非常有用:
Environment
上的Arch Wiki条目>针对管理员的systemd,第IX部分:在/ etc / sysconfig和/ etc / default上(由systemd的首席开发人员Lennart Poettering开发)
Systemd上针对Upstart用户的Ubuntu Wiki条目
评论
在为非oneshot类型的服务设置变量之前,必须先清除该变量。这解决了我的问题。
–科林
16年4月2日在16:26
来自于systemd.service(5)联机帮助页上ExecStart上的@MarkEdington:“除非Type =是oneshot,否则必须给出一个命令。使用Type = oneshot时,可以指定零个或多个命令。如果在同一指令中提供多个命令行,或者可以多次指定该指令,但效果相同如果将空字符串分配给该选项,则会重置要启动的命令列表,该选项的先前分配没有效果。”
–muru
17年8月31日在4:53
@Orient可以先先替换覆盖文件,然后再重新启动systemctl守护进程,或者可以对systemctl进行编辑,并用注释替换所有覆盖。服务文件中的注释以#开头。
–muru
18年1月19日在8:26
@Orient systemctl还原foo
–ayell
18年4月16日在5:36
这三种方法(覆盖文件,环境文件,环境变量)的优先顺序是什么?即,对于所有三个定义的变量,哪个值是有效的?
– Nikolaos Kakouros
19年6月16日在21:55
评论
请注意,用空白条目清除ExecStart =时,您不能在其后加上注释:ExecStart =#空行以清除以前的条目。这将作为另一个ExecStart =条目并添加到列表中。 PS。由于声誉低下,我无法在评论中添加评论。