Come posso sostituire o configurare i servizi di systemd?


109

Molti script init sysv hanno utilizzato un file corrispondente /etc/defaultper consentire all'amministratore di configurarlo. I lavori di avvio possono essere modificati utilizzando i .overridefile. Come posso sovrascrivere o configurare le unità systemd, ora che systemd è l'impostazione predefinita in Ubuntu?


Si noti che quando si cancella il messaggio ExecStart=con una voce vuota non è possibile inserire un commento dopo di esso come: ExecStart= # Empty line to clear previous entries.Verrà preso come un'altra ExecStart=voce e aggiunto all'elenco. PS. Non ho potuto aggiungere commenti alla risposta di Muru a causa della mia scarsa reputazione.
martedì

Risposte:


185

systemdle unità non devono obbedire ai file /etc/default. systemdè facilmente configurabile, ma richiede la conoscenza della sintassi dei file di unità di sistema.

I pacchetti spediscono file di unità in genere /lib/systemd/system/. Questi non devono essere modificati. Invece, systemdti permette di sovrascrivere questi file creando file appropriati in /etc/systemd/system/.

Per un determinato servizio foo, il pacchetto fornirebbe /lib/systemd/system/foo.service. Puoi controllare il suo stato usando systemctl status fooo visualizzare i suoi registri usando journalctl -u foo. Per sovrascrivere qualcosa nella definizione di foo, fare:

sudo systemctl edit foo

Questo crea una directory in /etc/systemd/systemnome dopo l'unità e un override.conffile in quella directory ( /etc/systemd/system/foo.service.d/override.conf). Puoi aggiungere o sovrascrivere le impostazioni usando questo file (o altri .conffile in /etc/systemd/system/foo.service.d/).

Sostituzione degli argomenti dei comandi

Prendi il gettyservizio per esempio. Supponiamo di voler avere un accesso automatico TTY2 al mio utente (questo non è consigliabile, ma solo un esempio). TTY2 è gestito dal getty@tty2servizio ( tty2essendo un'istanza del modello /lib/systemd/system/getty@service). Per fare questo, devo modificare il getty@tty2servizio.

$ 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

In particolare, devo cambiare la ExecStartlinea, che attualmente è:

$ systemctl cat getty@tty2 | grep Exec     
ExecStart=-/sbin/agetty --noclear %I $TERM

Per ignorare questo, fai:

sudo systemctl edit getty@tty2

E aggiungi:

[Service]
ExecStart=
ExecStart=-/sbin/agetty -a muru --noclear %I $TERM

Nota che:

  1. Ho dovuto esplicitamente chiaro ExecStartprima di impostare di nuovo, in quanto è un ambiente additiva, simile a After, Environment(nel suo insieme, non per-variabile) e EnvironmentFile, e al contrario di come modificare le impostazioni dei RestartSeco Type. ExecStartpuò avere più voci solo per i Type=oneshotservizi.
  2. Ho dovuto usare l'intestazione della sezione corretta. Nel file originale, ExecStartè nella [Service]sezione, quindi anche la mia sostituzione deve essere inserita ExecStartnella [Service]sezione. Spesso, dando un'occhiata al file di servizio effettivo utilizzato systemctl catti dirà cosa devi sovrascrivere e in quale sezione si trova.

Di solito, se si modifica un file di unità di sistema, affinché abbia effetto, è necessario eseguire:

sudo systemctl daemon-reload

Tuttavia, lo systemctl editfa automaticamente per te.

Adesso:

$ 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 ; ... }

E se lo faccio:

sudo systemctl restart getty@tty2

e premi CtrlAltF2presto! Verrò effettuato l'accesso al mio account su quel TTY.

Come ho detto prima, getty@tty2è un'istanza di un modello. Quindi, se volessi ignorare tutte le istanze di quel modello? Ciò può essere fatto modificando il modello stesso (rimuovendo l'identificatore dell'istanza - in questo caso tty2):

systemctl edit getty@

Sovrascrivere l'ambiente

Un caso d'uso comune di /etc/defaultfile è l'impostazione delle variabili di ambiente. Di solito, /etc/defaultè uno script di shell, quindi è possibile utilizzare costrutti di linguaggio di shell in esso. Con systemd, tuttavia, non è così. È possibile specificare le variabili di ambiente in due modi:

Tramite un file

Supponi di aver impostato le variabili di ambiente in un file:

$ cat /path/to/some/file
FOO=bar

Quindi, è possibile aggiungere alla sostituzione:

[Service]
EnvironmentFile=/path/to/some/file

In particolare, se /etc/default/grubcontiene solo assegnazioni e nessuna sintassi della shell, è possibile utilizzarlo come EnvironmentFile.

Via Environmentvoci

Quanto sopra potrebbe anche essere realizzato utilizzando la seguente sostituzione:

[Service]
Environment=FOO=bar

Tuttavia, questo può diventare complicato con più variabili, spazi, ecc. Dai un'occhiata a una delle mie altre risposte per un esempio di tale istanza.

Ulteriori letture

Tramite questo meccanismo, diventa molto facile sovrascrivere le systemdunità, nonché annullare tali modifiche (semplicemente rimuovendo il file di sostituzione). Queste non sono le uniche impostazioni che possono essere modificate.

I seguenti collegamenti sarebbero utili:


1
Devi cancellare la variabile prima di impostarla per servizi non del tipo oneshot. Questo ha risolto il mio problema.
Colin,

3
@MarkEdington dalla systemd.service(5)manpage, sezione su ExecStart: "A meno che Type = non sia oneshot, è necessario specificare esattamente un comando. Quando si utilizza Type = oneshot, è possibile specificare zero o più comandi. I comandi possono essere specificati fornendo più righe di comando nella stessa o, in alternativa, questa direttiva può essere specificata più di una volta con lo stesso effetto. Se la stringa vuota è assegnata a questa opzione, l'elenco dei comandi da avviare viene ripristinato, le precedenti assegnazioni di questa opzione non avranno alcun effetto. "
Muru,

1
@Orient è possibile sudo rmil file di sostituzione e quindi systemctl daemon-reload, oppure è possibile systemctl edite sostituire tutto nella sostituzione con commenti. I commenti nei file di servizio iniziano con #.
Muru,

3
@Orientsystemctl revert foo
Ayell

1
Qual è l'ordine di precedenza per i tre metodi (sovrascrivi file, file di ambiente, variabile di ambiente)? Vale a dire, per una variabile definita in tutti e tre, quale valore sarà quello effettivo?
Nikolaos Kakouros il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.