Was ist der richtige Ersatz für rc.local in systemd, anstatt rc.local neu zu erstellen?

25

Ich kann auf systemd einige lokale Skripte (oder sehr lokale Befehle) nicht korrekt ausführen. Ich weiß bereits, dass ich keinen Dienst (in systemd eine Einheit) für diese Art von Skripten erstellen darf (oder muss ich?).

Die Problemumgehung, die ich gefunden habe, besteht darin, rc.local zu erstellen und ihm Ausführungsberechtigungen zu erteilen.

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

Wenn ich zum Beispiel einen Legacy-Server mit einer von Ihnen konfigurierten einfachen rc.local bekomme, weiß ich, was Sie getan haben und wie sehr es wehtun wird, etwas Neues in der Distribution zu aktualisieren oder zu installieren, da rc.local von external respektiert wurde Pakete, aber auf der anderen Seite, wenn ich einen Server installiere und eine systemd-Einheit oder zwei oder drei (oder sogar sysvinit-Dienste) erstelle, nur um eine einfache Aufgabe zu erledigen, kann dies manchmal Ihr Leben erschweren und viel mehr als dies meine Einheiten Namen können eines Tages zu Konflikten mit den Namen der neuen Dienste führen, die von der Distributionsentwicklung erstellt und möglicherweise bei einem Upgrade installiert wurden, was zu Problemen bei meinen Skripten führen kann!

Ich sehe eine andere Frage zu fragen , wo ist rc.local und die Antwort war , um es zu erstellen und Ausführungsberechtigungen zu geben, ich glaube , meine Frage ist wirklich nicht ein Duplikat , weil ich möchte nicht wissen , wo es ist - glauben Sie mir, ich will nur zu akzeptieren, dass es veraltet ist , aber ich kann nicht den richtigen Weg finden, um solche Dinge zu tun, sollte ich wirklich eine Einheit nur für solche einfachen Dinge schaffen?

Luciano Andress Martini
quelle
4
systemd "der einzige Gewinnzug ist, nicht zu spielen"; Alternativ können Sie je nach Bedarf eine Systemeinheit erstellen. Ich würde wahrscheinlich rc.local für den Moment verwenden und mich darum kümmern, wenn es verschwindet.
Rui F Ribeiro
Sie glauben also, der offizielle Weg ist, eine Einheit wie einen Dienst zu schaffen? Bitte poste als Antwort, wie das geht.
Luciano Andress Martini
1
Als ich Ubuntu ausprobierte, erstellte ich eine Unit, um einen permanenten ssh-agent-Cache auf meinem Desktop zu haben, während ich nicht neu gestartet habe, und eine andere für etwas anderes, an das ich mich nicht erinnern kann. Sie können auch einen Verweis auf /etc/rc.local erstellen, aber es scheint, dass das System dies vorerst für sich selbst tut. Ich würde vorerst einen Verweis auf eine Fälschung erstellen /etc/rc.local dann.
Rui F Ribeiro
Dies führt wahrscheinlich dazu, dass Dokumentationen beschädigt werden, als ob in einem Buch angegeben wird, dass Sie etwas in /etc/rc.local einfügen müssen, und Sie versuchen, dieses Dokument zu aktualisieren, indem beispielsweise angegeben wird, dass rc.local als ausführbar markiert werden muss, wenn es vollständig veraltet ist Die Dokumentation ist fehlerhaft. Wenn Sie jedoch angeben, dass Sie eine Unit erstellen müssen, um auf /etc/rc.local zu verweisen, wird die Dokumentation beschädigt, da systemd mit Ihrer Unit in Konflikt steht. Ich glaube, wenn Sie Recht haben, haben sie wahrscheinlich nicht entschieden, ob es veraltet ist oder nicht, weil sie immer noch keinen Ersatz haben ... wenn sie entscheiden, dass alle Unterlagen wieder kaputt gehen.
Luciano Andress Martini
Welche Art von Skript müssen Sie ausführen? Systemd hat viele Einheitentypen. "Service" ist nur einer von vielen Gerätetypen . ZB Mount-Einheiten, Automount-Einheiten, Timer-Einheiten, Zieleinheiten. Könnte einer von ihnen Ihr Problem lösen?
Andcoz

Antworten:

17

Wie bereits an anderer Stelle erwähnt, wird es mäßig unrein, rc-local.serviceunter zu verwenden systemd.

  1. Es ist theoretisch möglich, dass Ihre Distribution dies nicht ermöglicht. (Ich denke, das ist nicht üblich, zB weil das Deaktivieren der gleichen Build-Option auch poweroff/ reboot-Befehle entfernt, die viele Leute verwenden).
  2. Die Semantik ist nicht ganz klar. Systemd definiert rc-local.serviceeine Möglichkeit, aber Debian bietet eine Drop-In-Datei, die mindestens eine wichtige Einstellung ändert.

rc-local.servicekann oft gut funktionieren. Wenn Sie sich darüber Sorgen machen, müssen Sie nur eine eigene Kopie davon erstellen! Hier ist die Magie:

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

[Install]
WantedBy=multi-user.target

Ich glaube nicht, dass Sie jedes einzelne Detail verstehen müssen [*], aber es gibt zwei Dinge, die Sie hier wissen müssen.

  1. Sie müssen dies mit aktivieren systemctl enable my-startup.service.

  2. Wenn Ihr Skript von einem anderen Dienst abhängig ist, einschließlich network-online.target, müssen Sie ihn deklarieren. ZB einen [Unit]Abschnitt hinzufügen , mit den Linien Wants=network-online.targetund After=network-online.target.

    Sie müssen sich keine Gedanken über Abhängigkeiten von "Early Boot" -Diensten machen - insbesondere von Diensten, die bereits zuvor bestellt wurden basic.target. Dienstleistungen wie my-startup.servicewerden automatisch nachbestellt basic.target, sofern sie nicht eingestellt sind DefaultDependencies=no.

    Wenn Sie nicht sicher sind, ob es sich bei einer Ihrer Abhängigkeiten um einen "Early Boot" -Dienst handelt, besteht ein Ansatz darin, die zuvor geordneten Dienste basic.targetdurch Ausführen aufzulisten systemctl list-dependencies --after basic.target. (Beachten Sie, das --afterist nicht --before).

Es gibt einige Überlegungen, die meiner Meinung nach auch für Pre-Systemd gelten rc.local:

  1. Sie müssen sicherstellen, dass Ihre Befehle nicht mit einem anderen Programm in Konflikt stehen, das versucht, dasselbe zu steuern.
  2. Es ist am besten, keine lang laufenden Programme, auch bekannt als Daemons, zu starten rc.local.

[*] Ich habe Type=oneshot+ verwendet, RemainAfterExit=yesweil es für die meisten One-Shot-Skripte sinnvoller ist. Es wird formalisiert, dass Sie eine Reihe von Befehlen ausführen, die my-startupnach Abschluss als "aktiv" angezeigt werden und dass Sie keinen Dämon starten.

sourcejedi
quelle
Nun, es gibt eine Art "lokalen" Ort zum Erstellen von Services oder Snippets, oder was auch immer - oder kann ich darauf vertrauen, dass dies lokal ist und nicht geändert werden sollte? Wenn ich meine eigenen Dämonen entwickle? Da ich die Originalität des Systems nicht ändern möchte, möchte ich bei der Installation von apt-get nicht, dass mein System wegen eines ersetzten Skripts oder ähnlichem in Brand gerät. Ich möchte nur darauf vertrauen, dass der Daemon nur einmal gestartet wird, ohne zusätzliche verrückte Dinge zu tun, die ich fürchte ... wie den Versuch, ihn als unendlich neu zu starten, wenn er kaputt ist, etc ...
Luciano Andress Martini
1
@LucianoAndressMartini Wenn Sie nach dem richtigen Start eines Daemons fragen, sollten Sie wirklich einen individuellen Service dafür definieren. Das kann eine native Systemeinheit .servicesein, oder wenn Sie wirklich ein LSB-Init-Skript schreiben möchten, können Sie dies stattdessen tun. Ich wollte nicht empfehlen, mehrere Daemons rc-local.serviceoder ein gleichwertiges Element hinzuzufügen. Ich denke, es funktioniert wahrscheinlich, aber es scheint viel besser zu sein, wenn Sie den einzelnen Daemon systemctl restart my-daemonwie alles andere neu starten können. Es ist beabsichtigt, dass Sie Ihre lokalen Dienste in setzen /etc/systemd/system.
Sourcejedi
1
@LucianoAndressMartini Sie müssen vermeiden, denselben Namen wie bei jedem anderen Dienst zu verwenden - genau wie bei sysvinit. In ähnlichen Situationen habe ich meine Namen manchmal mit local-...
sourcejedi
1
Vielen Dank!!! Nach einem halben Tag gerettet. Diese Details waren für mich von entscheidender Bedeutung: Typ = oneshot, RemainAfterExit = yes, Wants = network-online.target, After = network-online.target. Sie müssen lediglich einen Build von Apache bereitstellen und die statische IP auf 192.168.1.80 festlegen, damit der Router den Datenverkehr dorthin leiten kann. Sollte trivial sein. Es ist nervig in Debian9. Kaum ein Online-Rat außer "apt-get apache", "systemctl start apache" oder Anweisungen mit init.d, von denen keine für Apache unter Debian9 gelten.
MichaelsonBritt
1
@MichaelsonBritt Es ist am besten, keine lang laufenden Programme, auch bekannt als Daemons, von rc.local aus zu starten. Ich habe Type=oneshot... es formalisiert, dass ... Sie keinen Daemon starten werden. Wenn Sie Informationen zum Starten eines Daemons benötigen, stellen Sie eine neue Frage.
Sourcejedi
15

Vergiss es rc.local.

Wie gesagt zu CentOS 7 und zu Debian 8 und zu Ubuntu 15 :

Sie verwenden ein systemd + Linux-Betriebssystem. /etc/rc.localist ein doppelter Abwärtskompatibilitätsmechanismus in systemd, da es sich um einen Abwärtskompatibilitätsmechanismus für einen Mechanismus handelt, der selbst ein Kompatibilitätsmechanismus im rcKlon von van Smoorenburg System 5 war .

Die Verwendung /etc/rc.localkann schrecklich schief gehen. Die Leute waren überrascht über die Tatsache, dass systemd nicht rc.localganz auf die gleiche Weise läuft , an der gleichen Stelle im Bootstrap, wie sie es gewohnt sind. (Oder fälschlicherweise erwartet: Es lief nicht zuletzt auf dem alten System, wie das OpenBSD-Handbuch immer noch feststellt.) Andere waren überrascht, dass das, was sie bei der rc.localErwartung der alten Art und Weise, Dinge zu tun, eingerichtet haben, ist dann vollständig durch die Gleichen von neuen rückgängig gemacht udevRegeln, Networkmanager systemd-logind, systemd-resolvedoder verschiedene „Kit“ s.

Wie am Beispiel von „ Excess Argumenten‚auf Arch installieren? Warum `init 0 'in Folge‘ “, bereits einige Betriebssysteme systemd bieten , ohne die Abwärtskompatibilität verfügt wie der systemd-rc-local-generatorGenerator . Während Debian die Abwärtskompatibilitätsfunktionen beibehält , erstellt Arch Linux systemd mit deaktivierten Funktionen . Also auf Arch und Betriebssystemen wie es erwarten /etc/rc.local , völlig ignoriert zu werden .

Vergiss es rc.local. Es ist nicht der richtige Weg. Sie haben ein systemd + Linux-Betriebssystem. Stellen Sie also eine ordnungsgemäße System-Service-Einheit her und beginnen Sie nicht an einem Punkt, der zwei Ebenen der Abwärtskompatibilität entfernt ist. (Auf Ubuntu und Fedora, es ist drei mal entfernt, das van Smoorenburg System 5 - rcKlon, gefolgt rc.localdann gewesen sich zweimal überholt, vor über einem Jahrzehnt, die zuerst von Emporkömmling und dann von systemd.)

Denken Sie auch an die erste Regel für die Migration zu systemd .

Dies ist nicht einmal eine neue systemd-spezifische Idee. Auf van Smoorenburg- rcund Upstart-Systemen musste statt der Verwendung ein ordnungsgemäßes van Smoorenburg- rcSkript oder eine Upstart- Jobdatei erstellt werden rc.local. Sogar das Handbuch von FreeBSD stellt fest, dass man heutzutage ein richtiges Mewburn- rcSkript erstellt, anstatt es zu verwenden /etc/rc.local. Mewburn rcwurde 2000 von NetBSD 1.5 eingeführt.

/etc/rc.localstammt aus der Zeit von Seventh Edition Unix und früher. Es wurde von AT & T Unix System 3 (mit einem etwas anderen in AT & T Unix System 5) im Jahr 1983 abgelöst /etc/inittabund auf Runlevel-Basis . Auch das ist jetzt Geschichte.rc/etc/inittab

Erstellen Sie geeignete native Service-Definitionen für Ihr Service-Management-System, sei es ein Service-Bundle für das nosh-Toolset service-managerund system-controlein /etc/rc.d/Skript für Mewburn rc, eine Service-Unit-Datei für systemd, eine Job-Datei für Upstart oder ein Service-Verzeichnis für runit / s6 / daemontools -encore oder sogar ein /etc/init.d/Drehbuch für van Smoorenburg rc.

In systemd gehen solche vom Administrator hinzugefügten Service-Unit-Dateien /etc/systemd/system/normalerweise (oder /usr/local/lib/systemd/system/selten) ein. Mit dem nosh Service Manager /var/local/sv/ist ein herkömmlicher Ort für lokale Service-Bundles. Mewburn rcunter FreeBSD verwendet /usr/local/etc/rc.d/. Gepackte Service-Unit-Dateien und Service-Bundles, falls Sie sie erstellen, befinden sich jedoch an verschiedenen Orten.

Weitere Lektüre

JdeBP
quelle
2
@LucianoAndressMartini Eine bessere Frage wäre, wie man mit einem bestimmten Ausschnitt von rc.local in einem systemd-Dienst umgeht. Wenn Sie also ein bestimmtes Snippet haben (Sie erwähnen Anweisungen aus der Dokumentation einer bestimmten Software), stellen Sie stattdessen möglicherweise eine Frage zu diesem Snippet. Es gibt bestimmte allgemeine Regeln, die für die Konvertierung verwendet werden können, aber Sie können mehr daraus machen, wenn Sie die Funktionen der von Ihnen ausgeführten Software ausnutzen (z. B. im Vordergrund laufen, keine Dämonisierung versuchen usw.) und nach einem bestimmten Fall fragen könnte hilfreich sein.
Filbranden
4
Sie müssen sich fragen, ob es die Abwertung seit 1983 überlebt hat, vielleicht hat es etwas zu bieten?
Dan Carter
4
Diese Antwort ist predigend und kann die einfache Frage "Was soll ich stattdessen tun?" Nicht beantworten. Es kann Informationen enthalten und jede Menge Referenzen bereitstellen, aber den Zweck des Stapelaustauschs zunichte machen.
GPS
Ich bringe dies (das Ende von rc.local) zusammen mit DNS-Problemen zur Sprache, als Gründe, warum Linux sich nicht weiterentwickelt, aber tatsächlich immer mehr Spaghetti-Code wird. Systemd ist für viele eine Blackbox geworden. Wenn ein Benutzer oder Administrator etwas in rc.local ablegen möchte und dies nicht mehr kann, ist es nicht hilfreich, ihn zu zwingen, zuerst systemd-Kurse oder was auch immer Sie sonst predigen, um das gleiche Endergebnis in Tagen anstelle von Minuten zu erzielen. Natürlich können Idioten mit allem, was gut funktioniert und leicht zu handhaben ist, dumme Sachen machen, das ist niemals ein gültiges Argument, um es zu beenden.
Julius
2

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

Erstellen Sie /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

Dann:

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

Erkundigen Sie sich bei:

sudo systemctl start rc-local.service
sudo systemctl status rc-local.service
Ole Tange
quelle
Das von systemd bereitgestellte System StandardOutput=journal+console(Konsole entspricht in Ihrem Beispiel tty) scheint für die Fehlerbehebung viel nützlicher zu sein. Auch die Unterstützung für SysVStartPriority=wurde irgendwann entfernt. Vielleicht können Sie kommentieren, wie wichtig es SysVStartPriority=ist, oder es entfernen. Abgesehen davon ist es eine anständige Antwort.
Sourcejedi