Qual è il sostituto corretto di rc.local in systemd invece di ricreare rc.local


25

Non riesco a trovare il modo corretto di eseguire alcuni script locali (o comandi molto locali) su systemd, so già che non devo creare un servizio (in systemd un'unità) per questo tipo di script (o devo?) ....

La soluzione alternativa che ho trovato è creare rc.local e assegnargli permessi di esecuzione.

printf '#!/bin/bash \n\nexit 0' >/etc/rc.local 
chmod +x /etc/rc.local

Ad esempio, se ottengo un server legacy con un semplice rc.local configurato da te, saprò cosa hai fatto e quanto ti farà male aggiornare o installare qualcosa di nuovo sulla distribuzione, poiché rc.local è stato rispettato da esterno pacchetti, ma d'altra parte se installo un server e creo un'unità di sistema o due o tre (o anche servizi di sysvinit), solo per fare un semplice compito, questo a volte può rendere la vita più dura, e molto più di questo le mie unità i nomi possono un giorno essere in conflitto con i nomi dei nuovi servizi creati dallo sviluppo della distribuzione e forse installati su un aggiornamento, causando problemi ai miei script!

Vedo un'altra domanda chiedeva di dove è rc.local e la risposta è stata di creare e dare i permessi di esecuzione, penso che la mia domanda è in realtà non è un duplicato , perché io non voglio sapere dove si trova - mi creda, voglio solo per accettare che è deprecato , ma non riesco a trovare il modo corretto di fare questo tipo di cose, dovrei davvero creare un'unità solo per alcune cose del genere?


4
systemd "l'unica mossa vincente è non giocare"; in alternativa, a seconda di ciò che si desidera, è possibile creare un'unità Systemd. Probabilmente userei rc.local per ora e me ne occuperei quando scompare.
Rui F Ribeiro,

Quindi pensi che il modo ufficiale sia creare un'unità come un servizio? Si prega di inviare come risposta come farlo.
Luciano Andress Martini,

1
Quando ho provato Ubuntu ho creato un'unità per avere una cache ssh-agent persistente sul mio desktop mentre non ho riavviato e un'altra per qualcos'altro che non ricordo; puoi anche crearne uno che punta a /etc/rc.local ma sembra che il sistema lo stia facendo per te per ora .... Vorrei ora rc.local, e se è interrotto, crearne uno che punta a un falso /etc/rc.local quindi.
Rui F Ribeiro,

È probabile che ciò rompa la documentazione come se alcuni libri dicessero che devi inserire qualcosa in /etc/rc.local e provi ad aggiornare questi documenti, dicendo ad esempio che rc.local deve essere contrassegnato come eseguibile, quando diventa totalmente deprecato la documentazione è rotta, ma se si dice che è necessario creare unità per puntare a /etc/rc.local, questa interrompe la documentazione perché systemd è in conflitto con l'unità. Credo che se hai ragione, probabilmente non hanno deciso se è deprecato o meno, perché non hanno ancora un sostituto ... quando decidono che tutta la documentazione verrà nuovamente violata.
Luciano Andress Martini,

Che tipo di script devi eseguire? Systemd ha molti tipi di unità. "Service" è solo uno dei molti tipi di unità . Ad esempio, montare unità, unità di montaggio automatico, unità timer, unità target. Uno di loro potrebbe risolvere il tuo problema?
Andcoz,

Risposte:


17

Come sottolineato altrove, diventa moderatamente impuro da usare rc-local.servicesotto systemd.

  1. È teoricamente possibile che la tua distribuzione non lo abiliti. (Credo che questo non è comune, ad esempio perché disabilitando la stessa opzione di compilazione rimuove anche poweroff/ rebootcomandi che un sacco di gente usa).
  2. La semantica non è del tutto chiara. Systemd definisce rc-local.serviceun modo, ma Debian fornisce un file drop-in che altera almeno un'impostazione importante.

rc-local.servicepuò spesso funzionare bene. Se sei preoccupato per quanto sopra, tutto ciò che devi fare è crearne una tua copia! Ecco la magia:

# /etc/systemd/system/my-startup.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/libexec/my-startup-script

[Install]
WantedBy=multi-user.target

Non penso che tu debba capire ogni singolo dettaglio [*], ma ci sono due cose che devi sapere qui.

  1. È necessario abilitare questo con systemctl enable my-startup.service.

  2. Se lo script ha una dipendenza da qualsiasi altro servizio, incluso network-online.target, è necessario dichiararlo. Ad esempio aggiungere una [Unit]sezione, con le linee Wants=network-online.targete After=network-online.target.

    Non devi preoccuparti delle dipendenze dai servizi di "avvio anticipato", in particolare dei servizi già ordinati in precedenza basic.target. I servizi come my-startup.servicevengono ordinati automaticamente dopo basic.target, a meno che non vengano impostati DefaultDependencies=no.

    Se non sei sicuro che una delle tue dipendenze sia un servizio di "avvio anticipato", un approccio è quello di elencare i servizi ordinati in precedenza basic.target, eseguendo systemctl list-dependencies --after basic.target. (Nota che --afternon è così --before).

Ci sono alcune considerazioni che ritengo valga anche per pre-systemd rc.local:

  1. Devi assicurarti che i tuoi comandi non siano in conflitto con un altro programma che tenta di controllare la stessa cosa.
  2. È meglio non avviare programmi di lunga durata noti come daemon rc.local.

[*] Ho usato Type=oneshot+ RemainAfterExit=yesperché ha più senso per la maggior parte degli script one-shot. Formalizza che eseguirai una serie di comandi, che my-startupverranno mostrati come "attivi" una volta completati e che non avvierai un demone.


Bene, esiste una sorta di spazio "locale" per la creazione di servizi o frammenti, o altro - o posso fidarmi che questo sia locale e non debba essere modificato? se sviluppo i miei demoni? Perché non voglio alterare l'originalità del sistema, quindi quando installo qualche apt-get non voglio vedere il mio sistema in fiamme a causa di uno script sostituito, o qualcosa del genere per esempio. Voglio solo fidarmi che il demone verrà avviato solo una volta, senza fare ulteriori cose folli che temo ... come cercare di riavviarlo come infinito se è rotto, ecc ...
Luciano Andress Martini

1
@LucianoAndressMartini se stai chiedendo quale sia il modo giusto di avviare un demone, dovresti davvero definire un singolo servizio per esso. Può essere .serviceun'unità di sistema nativa , o se vuoi davvero scrivere uno script init LSB puoi farlo. Non volevo raccomandare di inserire diversi demoni rc-local.serviceo equivalenti, penso che probabilmente funzioni, ma sembra molto più bello se riesci a riavviare il singolo demone con systemctl restart my-daemonqualsiasi altra cosa. È previsto che tu inserisca i tuoi servizi locali /etc/systemd/system.
sourcejedi

1
@LucianoAndressMartini devi evitare di usare lo stesso nome di qualsiasi altro servizio, proprio come in sysvinit. In situazioni simili a volte ho iniziato i miei nomi con local-...
sourcejedi

1
Grazie!!! Salvato dopo mezza giornata. Questi dettagli sono stati fondamentali per me: Type = oneshot, RemainAfterExit = yes, Wants = network-online.target, After = network-online.target. Basta distribuire una build di apache e impostare l'IP statico su 192.168.1.80, in modo che il router possa indirizzare il traffico lì. Dovrebbe essere banale. È fastidioso in Debian9. Quasi nessun consiglio online, tranne "apt-get apache", "systemctl start apache" o istruzioni con init.d, nessuno dei quali si applica ad Apache costruito su sorgenti in Debian9.
MichaelsonBritt

1
@MichaelsonBritt È meglio non avviare programmi di lunga durata noti come demoni da rc.local. Ho usato Type=oneshot... formalizza che ... non avvierai un demone. Se desideri informazioni sull'avvio di un demone, fai una nuova domanda.
sourcejedi

15

Dimentica rc.local.

Come ho detto su CentOS 7 e su Debian 8 e su Ubuntu 15 :

Stai utilizzando un sistema operativo systemd + Linux. /etc/rc.localè un doppio meccanismo di compatibilità all'indietro in systemd, perché è un meccanismo di compatibilità all'indietro per un meccanismo che era esso stesso un meccanismo di compatibilità nel rcclone di Van Smoorenburg System 5 .

L'uso /etc/rc.localpuò andare terribilmente storto. Le persone sono state sorprese dal fatto che systemd non funziona rc.localallo stesso modo, nello stesso posto nel bootstrap, a cui sono abituati. (O si aspettano erroneamente: in effetti, non è durato per ultimo nel vecchio sistema, come sottolinea ancora il manuale di OpenBSD.) Altri sono rimasti sorpresi dal fatto che ciò che hanno impostato rc.localaspettandosi i vecchi modi di fare le cose, è poi completamente annullato da artisti del calibro di nuove udevregole, NetworkManager, systemd-logind, systemd-resolved, o diversi "kit" s.

Come esemplificato da " Perché" init 0 "si traduce in" Argomenti in eccesso "durante l'installazione di Arch? ", Alcuni sistemi operativi forniscono già systemd senza le funzionalità di retrocompatibilità come il systemd-rc-local-generatorgeneratore . Mentre Debian conserva ancora le funzionalità di retrocompatibilità , Arch Linux costruisce systemd con esse disattivate . Quindi su Arch e sistemi operativi come questo si aspettano /etc/rc.local di essere completamente ignorati .

Dimentica rc.local. Non è la strada da percorrere. Hai un sistema operativo systemd + Linux. Quindi crea una corretta unità di servizio di sistema e non iniziare da un punto che è lontano due livelli di compatibilità all'indietro. (Su Ubuntu e Fedora, viene rimosso tre volte, il rcclone di Van Smoorenburg System 5 che ne è seguito è rc.localstato poi sostituito due volte , oltre un decennio fa, prima da start-up e poi da systemd.)

Ricorda anche la prima regola per la migrazione a systemd .

Questa non è nemmeno una nuova idea specifica per systemd. Sui sistemi van Smoorenburg rce Upstart, la cosa da fare era creare un corretto rcscript di Van Smoorenburg o un file di lavoro Upstart anziché utilizzarlo rc.local. Perfino il manuale di FreeBSD fa notare che oggigiorno si crea uno rcscript Mewburn corretto invece di usarlo /etc/rc.local. Mewburn è rcstato introdotto da NetBSD 1.5 nel 2000.

/etc/rc.localrisale al tempo della Settima Edizione Unix e precedenti. È stato sostituito da /etc/inittabe basato su runlevel rcin AT&T Unix System 3 (con un leggermente diverso /etc/inittabin AT&T Unix System 5) nel 1983 . Anche questa è ormai storia.

Crea definizioni di servizio native appropriate per il tuo sistema di gestione dei servizi, che si tratti di un pacchetto di servizi per il set di strumenti di nosh service-managere system-control, uno /etc/rc.d/script per Mewburn rc, un file di unità di servizio per systemd, un file di lavoro per Upstart, una directory di servizio per runit / s6 / daemontools -encore, o anche una /etc/init.d/sceneggiatura per van Smoorenburg rc.

In systemd, tali file di unità di servizio aggiunti dall'amministratore vanno di /etc/systemd/system/solito (o /usr/local/lib/systemd/system/raramente). Con nosh service manager, /var/local/sv/è un luogo convenzionale per i bundle di servizi locali. Mewburn rcsu FreeBSD usa /usr/local/etc/rc.d/. I file di unità di servizio in pacchetto e i pacchetti di servizi, se li stai realizzando, vanno in luoghi diversi.

Ulteriori letture


2
@LucianoAndressMartini Una domanda migliore sarebbe come gestire uno snippet specifico di rc.local in un servizio systemd. Quindi, se hai in mente uno snippet specifico (menzioni le istruzioni dalla documentazione di alcuni software), potresti invece pubblicare una domanda su quello? Esistono alcune regole generali che possono essere utilizzate per la conversione, ma ne ottieni di più sfruttando le funzionalità del software che stai eseguendo (come l'esecuzione in primo piano, non cercando di demonizzare, ecc.) Quindi chiedendo un caso specifico potrebbe essere utile.
filbranden,

4
Devi chiederti se è sopravvissuto alla deprecazione dal 1983, forse ha qualcosa da fare?
Dan Carter,

4
Questa risposta è predicativa e non riesce proprio a rispondere alla semplice domanda "che cosa banale dovrei fare invece". Può contenere informazioni e fornire tonnellate di riferimenti, ma vanifica lo scopo di stackexchange.
gps

Ho portato questo (la fine di rc.local), insieme ai problemi di risoluzione dei dns, come ragioni per cui Linux non si sta evolvendo, ma in realtà sta diventando sempre più spaghetti-code, systemd è diventato una scatola nera per molti. Se un utente o un amministratore desidera inserire qualcosa in rc.local e non è più possibile, non è utile costringerli a fare prima i corsi di sistema o qualsiasi altra cosa tu predichi al fine di ottenere lo stesso risultato finale in giorni, anziché minuti. Naturalmente, gli idioti possono fare cose stupide con tutto ciò che funziona bene ed è facile da lavorare, non è mai un argomento valido per finirlo.
Giulio

2

Riepilogo di https://www.linuxbabe.com/linux-server/how-to-enable-etcrc-local-with-systemd

Creare /etc/systemd/system/rc-local.service:

# /etc/systemd/system/rc-local.service
[Unit]
 Description=/etc/rc.local Compatibility
 ConditionPathExists=/etc/rc.local

[Service]
 Type=forking
 ExecStart=/etc/rc.local start
 TimeoutSec=0
 StandardOutput=tty
 RemainAfterExit=yes
 SysVStartPriority=99

[Install]
 WantedBy=multi-user.target

Poi:

sudo touch /etc/rc.local
sudo chmod +x /etc/rc.local
sudo systemctl enable rc-local

Controllare con:

sudo systemctl start rc-local.service
sudo systemctl status rc-local.service

Si utilizza quello fornito da systemd StandardOutput=journal+console(la console è equivalente a tty nell'esempio), il che sembra che sarebbe molto più utile per la risoluzione dei problemi. Anche il supporto per SysVStartPriority=è stato rimosso ad un certo punto. Forse potresti commentare quanto SysVStartPriority=è importante o rimuoverlo. A parte questo, è una risposta decente.
sourcejedi
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.