Wie starte ich einen Dienst automatisch, wenn Ubuntu startet?

31

Ich benutze Ubuntu 12.04 und möchte einen Dienst starten, wenn das System normal gebootet wird.

Als 'Dienst' verstehe ich einen Code, zum Beispiel cd mein_Verzeichnis; my_command -host 0.0.0.0 -port 1234 -arg x, das so ausgeführt werden sollte, als ob es in der Befehlszeile gestartet worden wäre. Es gibt Dienste, die als normaler Benutzer gestartet werden müssen, aber auch Dienste, die als Root gestartet werden müssen (tatsächlich müssen die Dienste nicht auf Benutzerebene ausgeführt werden).

Ich muss auch das Verhalten konfigurieren, wenn ein "Dienst" beendet wird. Ich möchte, dass sie in meinem Fall mit demselben Argument in einem angegebenen Verzeichnis neu gestartet werden.

Alle Dienste sollten automatisch gestartet werden, wenn das System normal gestartet wird, dh wenn der Netzschalter gedrückt wird. Es sollte keine weitere Aktion erforderlich sein.

Es gibt einige Dokumente, die im Internet verbreitet sind, aber alle verwirren mich. Sie sprechen über init, init.d, rc.d, aber ich sah nie eine einfach zu folgen Schritt- für -Schritt - Anleitung , um leicht als Service mit zB Emporkömmling. Wenn dies einfach ist, würde ich mich freuen, wenn diese Schritte hier angegeben werden.

Alex
quelle

Antworten:

33

Verwenden Sie das hier angegebene Beispiel, um einen Job zu erstellen, der beim Start von Ubuntu automatisch gestartet wird . Nehmen wir als schriftliches Beispiel an, Sie erstellen die folgende Datei /etc/init/testservice.confmit sudo:

# testservice - test service job file

description "my service description"
author "Me <[email protected]>"

# Stanzas
#
# Stanzas control when and how a process is started and stopped
# See a list of stanzas here: http://upstart.ubuntu.com/wiki/Stanzas

# When to start the service
start on runlevel [2345]

# When to stop the service
stop on runlevel [016]

# Automatically restart process if crashed
respawn

# Essentially lets upstart know the process will detach itself to the background
# This option does not seem to be of great importance, so it does not need to be set.
#expect fork

# Specify working directory
chdir /home/user/testcode

# Specify the process/command to start, e.g.
exec python mycommand.py arg1 arg2

Um den Prozess manuell zu starten oder zu stoppen, verwenden Sie

sudo start testservice
sudo stop testservice

Siehe die Jobsteuerungsbefehle .

Alex
quelle
Ich brauchte "start on started mountall", um den Dienst zu starten.
martinedwards
23

Ok, Alex, der Punkt ist, dass alle Userspace-Prozesse in Linux mit initprocess gestartet werden, dessen pid 1 ist. pstreeSehen Sie sich zum Beispiel den Baum Ihrer Prozesse an, dessen root init ist. initHeutzutage gibt es mehrere Versionen der Prozessimplementierung am bemerkenswertesten sind

  • sysVinit (klassisches Init, das immer noch von einigen Distributionen verwendet wird, einschließlich älterer Debian-Versionen)
  • Upstart init, wird von älteren Ubuntu und einigen RHEL (Red Hat) und älteren Fedora-Versionen verwendet
  • systemd init, wird von modernen Fedora-, Ubuntu-, Debian-, RHEL- und SUSE-Versionen verwendet

Traditionell verwendeten Unixe die Init-Implementierung sysVinitinit, die unter dem Namen https://ru.wikipedia.org/wiki/UNIX_System_V aufgerufen wurde Version von Unix . Es ist sehr einflussreich und andere Inits sind abwärtskompatibel.

Grundsätzlich liest sysVinit zuerst die /etc/inittabDatei, entscheidet, welcher Runlevel ausgeführt werden soll, und weist das /etc/init.d/rcSkript an, sogenannte Init-Skripte auszuführen. ZB wenn es normalerweise zu einem Mehrbenutzer-Runlevel bootet, was normalerweise Runlevel 2 unter Ubuntu ist , /etc/init.d/rcstartet es die Ausführung von Skripten in /etc/rc2.d. Dateien gibt es nur symbolische Links zu Skripten, während die Skripten selbst im /etc/init.dVerzeichnis gespeichert sind . Die Benennung dieser Symlinks in /etc/rc*.dVerzeichnissen lautet wie folgt. Angenommen, wir haben die folgenden Skripte in /etc/rc2.d:

$ls /etc/rc2.d
S16rsyslog
S17apache2
K02network-manager

Dies bedeutet, dass beim Umschalten auf Runlevel 2 init process zuerst network-managerProzesse beendet werden, da sein Skriptname mit K- K02network-managerund dann Prozesse startet, deren Namen mit beginnen S. Die zwei Ziffern nach Soder Ksind die Zahlen von 00 bis 99, die die Reihenfolge bestimmen, in der die Prozesse gestartet werden. ZB rsyslogwird sie vorher gestartet apache2, da 16 kleiner als 17 ist (dies ist sinnvoll, da Sie möchten, dass Apache sich auf die Protokollierungskapazitäten von rsyslog verlässt Daher sollte zuerst rsyslog gestartet werden. Die Skripte sind zufällige Shell-Skripte, die von ausgeführt werden #!/bin/sh.

Um ein Programm nach dem Start im sysVinit-Stil zu starten, müssen Sie zunächst ein eigenes Skript schreiben (indem Sie es aus einem Beispiel kopieren, in das Sie /etc/init.dhineingekommen sind), /etc/init.des unter einem vernünftigen Namen einfügen und einen Symlink dazu erstellen, z . B. S99mytrojanin /etc/rc2.d. Hier finden Sie eine Erklärung typischer sysVinit-Skripte in /etc/init.d http://docs.oracle.com/cd/E19683-01/806-4073/6jd67r96g/index.html

Jetzt haben sich die Ubuntu-Jungs entschieden, dass sie zusätzliche Funktionen von init wollen. Sie wollten ein schnelles Booten des Betriebssystems, also wollten sie, dass ihre Skripte parallel ausgeführt werden. Sie wollten, dass tote Prozesse automatisch neu gestartet werden. Sie wollten, dass die Prozesse sich gegenseitig explizit durch Ereignisse aufrufen (so dass Apache durch das Ereignis "syslog started" und Syslog durch das Ereignis "file systems mounted" usw. ausgeführt wird, sodass wir Ereignisse anstelle einiger Zahlen 00 haben -99). So haben sie Upstart gemacht und hier ist, wie es funktioniert. Upstart-Initskripte werden in ein /etc/initVerzeichnis gestellt (nicht verwechseln mit /etc/init.d). Upstart läuft normalerweise/etc/init.d/rcDa auch ausgeführt wird, werden Ihre sysVinit-Skripte normal ausgeführt. Wenn Sie jedoch möchten, dass Ihr Skript beim Beenden erneut angezeigt wird, sind Upstart-Ereignisse genau das Richtige für Sie.

Obwohl ich nicht überprüfen kann, ob mein Skript funktioniert, sollten Sie für Ihre Zwecke das folgende /etc/init/mytrojan.confSkript schreiben :

start on runlevel [02]
respawn
exec mytrojan --argument X 

Wenn Sie jedoch Abhängigkeiten benötigen, zumindest Dateisysteme und Netzwerk, ist es möglicherweise sinnvoll, diese durch Folgendes zu ersetzen start on runlevel [02]:

start on (local-filesystems and net-device-up IFACE!=lo)

WARNUNG: Ich habe die Richtigkeit nicht überprüft, weil ich nicht kann. Insbesondere bin ich mir nicht ganz sicher, wie ich das Skript starten soll, nachdem Ihre Netzwerkverbindung hergestellt wurde (ich habe diese Version verwendet ). Versuchen Sie, auf "Start im Netzwerk" zu googeln.

Boris Burkov
quelle
1
Dies ist eine sehr schöne Übersicht über die Geschichte der Prozesse, die unter Linux gestartet wurden, die jedoch nicht mit Fragen beantwortet werden. Ich weiß immer noch nicht, wie ich einen Upstart-Prozess erstellen soll. Ich möchte es auch nur benutzen, verstehe nicht jedes kleinste bisschen, wie es funktioniert. Ich wollte nur ein einfaches und benutzerfreundliches Beispiel dafür haben, wie man einen Prozess erstellt, der automatisch mit ubuntus upstart..l gestartet und neu erzeugt wird.
Alex
@Alex: aktualisiert mit einem Beispielscipt. Beachten Sie, dass mein Skript möglicherweise falsch ist. Ich habe es im Geiste von alexreisner.com/code/upstart gemacht .
Boris Burkov
1
Upvoted, weil dies eine der besten Antworten ist, die ich je gelesen habe.
user1301428