14Prozessverwaltung
Dieses Kapitel beschreibt, wie Linux mit Prozessen umgeht. Im Verlauf dieses Kapitels lernen Sie,-
welche Möglichkeiten es gibt, Programme zu starten und wieder zu beenden (zur Not auch gewaltsam),
-
wie Sie ein Programm mit root-Rechten ausführen,
-
was Dämonen sind und
-
wie Sie Programme zu bestimmten Zeiten automatisch starten können.
14.1Prozesse starten, verwalten und stoppen
In diesem Kapitel ist überwiegend von Prozessen die Rede. Ein Prozess ist auf Betriebssystemebene für die Ausführung eines Programms oder Kommandos verantwortlich. Das klingt nach einer eher trivialen Aufgabe; da aber eine Menge Programme und Hintergrunddienste parallel laufen, ist es gar nicht so einfach, die Rechenzeit zwischen allen Programmen gerecht bzw. sinnvoll zu verteilen.
Programme und Kommandos
Ein Programm bzw. ein Kommando ist eigentlich nur eine ausführbare Datei. Eine Programmdatei unterscheidet sich von anderen Dateien also dadurch, dass das Execute-Bit x gesetzt ist.
Linux-intern gibt es keine Unterscheidung zwischen einem Programm wie Firefox oder einem Kommando wie ls. Umgangssprachlich werden textorientierte Programme wie ls aber oft als Kommandos bezeichnet.
Erst durch den Start einer gleichsam leblosen Programmdatei wird diese zu einem lebendigen Prozess, der vom Linux-Kernel verwaltet wird. So gesehen müsste die Überschrift dieses Abschnitts eigentlich lauten: Programme und Kommandos starten, Prozesse verwalten und stoppen.
Hin und wieder taucht die Frage auf, wo denn unter Linux die *.exe-Dateien sind. Bis vor einigen Jahren hieß die richtige Antwort: Es gibt keine *.exe-Dateien. Ausführbare Programme sind durch das Zugriffsbit x gekennzeichnet; die von Windows bekannte Dateikennung *.exe ist somit überflüssig.
Mittlerweile ist diese Antwort insofern nicht mehr ganz richtig, als es unter Linux tatsächlich vereinzelte *.exe-Dateien geben kann. Dabei handelt es sich um Programme, die in der Programmiersprache C# entwickelt wurden und die zur Ausführung auf die Mono-Bibliothek zurückgreifen. Die Mono-Bibliothek ist wiederum eine Open-Source-Implementierung des .NET Frameworks von Microsoft.
Programme starten
Unter X starten Sie Programme im Regelfall über ein Menü oder durch das Anklicken eines Icons. Desktop-Systeme wie KDE, Gnome oder Unity bieten mit den Tastenkürzeln (Alt)+(F2) oder (é) eine weitere Möglichkeit, Programme rasch zu starten.
Alternativ können Sie Programme auch in einem Terminalfenster oder in einer Textkonsole starten. Dazu geben Sie einfach den Namen des Programms ein und drücken (¢). Gerade Linux-Profis wählen oft diesen Weg, weil es schneller geht, ein paar Buchstaben einzutippen, als das Programm in verzweigten Menüs zu suchen.
Normalerweise reicht es aus, wenn Sie einfach den Namen des Programms angeben. Der Shell-Interpreter sucht das Programm dann in allen Verzeichnissen, die in der Umgebungsvariable PATH angegeben sind. Die folgenden Zeilen zeigen eine typische Einstellung dieser Variable:
Wenn Sie ein Programm starten möchten, das sich in keinem dieser Verzeichnisse befindet, müssen Sie den vollständigen Pfad angeben. Das gilt auch für Programme im gerade aktuellen Verzeichnis! Hier wird der Pfad einfach durch einen Punkt angegeben, also beispielsweise ./meinprogramm.
Vordergrund- und Hintergrundprozesse
Wenn Sie Programme unter X per Menü starten, laufen diese selbstverständlich als sogenannte Hintergrundprozesse, also ohne sich gegenseitig zu behindern. Sie können weitere Programme starten, ohne auf das Ende der bisher gestarteten Programme warten zu müssen.
Ganz anders ist das Verhalten, wenn Sie ein Programm in einer Textkonsole bzw. einem Terminal ausführen. Das Programm wird als Vordergrundprozess gestartet. Bevor Sie im Terminal das nächste Kommando eingeben können, müssen Sie auf das Ende des zuletzt gestarteten Programms warten.
Aber auch in Textkonsolen oder Terminal-Fenstern können Sie Programme im Hintergrund starten. Dazu geben Sie einfach am Ende des Kommandos das Zeichen & an:
Wenn Sie & vergessen haben, können Sie das Programm auch nachträglich in einen Hintergrundprozess umwandeln. Unterbrechen Sie die Programmausführung mit (Strg)+(Z), und setzen Sie das Programm mit bg fort:
Wenn Sie statt bg das Kommando fg verwenden, wird das Programm als Vordergrundprozess fortgesetzt.
Bei manchen Kommandos stören diverse Textausgaben bei der Hintergrundausführung. Diese können Sie aber leicht unterdrücken, indem Sie sie nach /dev/null umleiten. Beispielsweise wird durch das folgende Kommando ein USB-Stick im Hintergrund formatiert:
Liste aller laufenden Prozesse (ps, top)
Eine Liste der zurzeit laufenden Prozesse können Sie sehr einfach mit ps erzeugen. Ohne Optionen zeigt ps nur Ihre eigenen Prozesse an – und nur solche, die aus Textkonsolen bzw. Shell-Fenstern gestartet wurden. ps kann durch zahllose Optionen gesteuert werden, wobei viele Optionen ohne das sonst übliche vorangestellte Minuszeichen angegeben werden. Wenn der Prozessname in eckigen Klammern steht, handelt es sich um einen Prozess des Kernels. Im folgenden Beispiel wurde die Liste der Prozesse aus Platzgründen stark gekürzt. Auf einem typischen Linux-System mit grafischer Benutzeroberfläche laufen normalerweise deutlich mehr als 100 Prozesse zugleich.
Praktischer als ps ist oft top: Dieses Kommando ordnet die Prozesse danach, wie sehr sie die CPU belasten, und zeigt die gerade aktiven Prozesse zuerst an. Das Programm gibt auch einen Überblick über den aktuellen Speicherbedarf etc. Die Prozessliste wird alle paar Sekunden aktualisiert, bis das Programm mit (Q) beendet wird. Die folgenden Zeilen zeigen einen Webserver nahezu im Leerlauf:
Der Wert in der PID-Spalte gibt die Prozessnummer an. Wenn Sie diese Nummer kennen, können Sie außer Kontrolle geratene Programme oder Hintergrundprozesse mit dem Kommando kill gewaltsam stoppen.
Prozesse können verschiedene Zustände annehmen. Die zwei häufigsten Zustände sind R (running) und S (sleeping, das Programm hat also gerade nichts zu tun und wartet auf Eingaben). Programme können auch vorübergehend unterbrochen werden und weisen dann den Zustand T (stopped) auf.
top nimmt auch interaktiv Kommandos entgegen. Damit können Sie Prozesse stoppen ((K), kill) oder ihre Priorität verändern ((R), renice).
Eine wesentlich komfortablere Alternative zu top ist das Kommando htop, das bei den meisten Distributionen separat installiert werden muss. Es erlaubt unter anderem ein horizontales und vertikales Scrollen in der Prozessliste.
Wenn Sie nicht die CPU- und Speicherauslastung, sondern die Zugriffe auf Festplatten und andere Datenträger verfolgen möchten, starten Sie statt top das Kommando iotop. Mit der Option -o schränken Sie die Ausgabe auf Prozesse ein, die tatsächlich IO-Aktivität verursachen. -u beschränkt die Ausgabe auf eigene Prozesse. iotop ist Bestandteil des gleichnamigen Pakets, das in der Regel extra installiert werden muss.
Wenn Sie den Programmnamen wissen und die dazugehörende Prozessnummer (PID) ermitteln möchten, hilft pidof. Wenn es mehrere Prozesse mit dem gleichen Namen gibt, liefert pidof eine ganze Liste von Nummern:
Manchmal ist es auch nützlich, festzustellen, welche Programme auf eine bestimmte Datei oder ein Verzeichnis zugreifen. Die entsprechenden Prozessnummern können Sie mit fuser feststellen. Ein Verzeichnis gilt auch dann als benutzt, wenn darin ein Programm gestartet wurde. Das folgende Kommando zeigt, dass die Shell bash das Verzeichnis /media/dvd nutzt:
Beachten Sie, dass ein Dateizugriff nur festgestellt werden kann, wenn das Programm die Datei wirklich geöffnet hat. Das ist bei einem Texteditor beispielsweise nicht der Fall: Der Editor hat die Datei zum Laden geöffnet, dann aber wieder geschlossen. Zum Speichern öffnet er die Datei wiederum nur für kurze Zeit.
Manche Hintergrundprozesse speichern im Verzeichnis /var/run eine PID-Datei, z.B. /var/run/httpd.pid. Diese Datei enthält in der ersten Zeile die Prozessnummer; weitere Zeilen können Zusatzinformationen enthalten, z.B. die Netzwerkschnittstelle. PID-Dateien ermöglichen das gezielte Beenden eines bestimmten Prozesses durch das Init-System, und zwar auch dann, wenn es mehrere gleichnamige Prozesse gibt.
Zu den Kommandos top und htop gibt es natürlich auch grafische Alternativen, z.B. ksysguard (KDE) oder gnome-system-monitor (Gnome). Ungleich mehr Darstellungs- und Konfigurationsmöglichkeiten bietet Conky. Dieses Programm zeigt Daten über die laufenden Prozesse an, aber auch alle erdenklichen anderen Statusinformationen, vom Datum bis hin zu den neuesten RSS-Feed-Eingängen. Wenn die Pakete lm-sensors und hddtemp installiert sind, kann Conky auch die CPU- und Festplattentemperatur anzeigen. Die Darstellung erfolgt direkt auf dem Desktop-Hintergrund, also nicht in einem eigenen Fenster. Die Konfiguration erfolgt durch die Textdatei .conkyrc.
In der Standardkonfiguration zeigt Conky relativ spärliche Informationen in einem schwarzen Rechteck links oben im Bildschirm an. In dieser Form bietet Conky nur wenige Vorteile im Vergleich zu einem Terminal mit top. Im Internet finden Sie aber Conky-Konfigurationen, die wahre Kunstwerke sind und aus einem faden Desktop-Hintergrund eine originelle und nützliche Informationszentrale machen. Leider ist das manuelle Einrichten einer Conky-Konfiguration mit viel Arbeit verbunden. Viele der im Internet angebotenen Konfigurationsdateien sind veraltet oder passen nur zu einer speziellen Distribution.
Auf Debian- und Ubuntu-Systemen hilft der Conky Manager bei der Installation fertiger Conky-Konfigurationen (siehe Abbildung 14.1). Für Ubuntu steht der Conky-Manager sogar in einer eigenen PPA-Paketquelle zur Verfügung.
http://teejeetech.blogspot.com/p/conky-manager.html
Abbildung 14.1Links der Conky-Manager mit einem Konfigurationsdialog, rechts eine Beispielkonfiguration
Wenn Sie nicht den eigenen Rechner überwachen möchten, sondern mehrere externe Server, können Sie dazu auf Tools wie Nagios oder Munin zurückgreifen. Deren Konfiguration ist aber alles andere als trivial und erfordert Routine bei der Server-Administration.
Eine wesentlich einfachere Alternative für einen einzelnen Server ist das Projekt »Linux Dash«. Nach der unkomplizierten Installation fasst eine im Webbrowser abrufbare Seite die wichtigsten Statusinformationen zusammen. Eine gute Einführung gibt dieser Heise-Artikel:
Prozesshierarchie
Intern wird mit jedem Prozess auch die PID-Nummer des Elternprozesses gespeichert. Diese Information ermöglicht die Darstellung eines Prozessbaums, an dessen Spitze immer der Init-Prozess steht. Das ist das erste Programm, das unmittelbar nach dem Laden des Kernels gestartet wird (siehe Kapitel 25, »Das Init-System«). In Abbildung 14.2 ist das systemd, d.h., die Abbildung wurde unter einer Distribution erstellt, die Systemd als Init-System verwendet.
Abbildung 14.2Prozessübersicht mit pstree
Das Kommando pstree, das mitunter extra installiert werden muss, zeigt die Hierarchie des Prozessbaums. Mit der Option -h werden die Elternprozesse zum gerade laufenden Prozess fett hervorgehoben. In Abbildung 14.2 ist das aber nicht zu sehen: Die so gekennzeichneten Prozesse folgen erst weiter unten, ich wollte in der Abbildung aber die Spitze des Prozessbaums zeigen.
Prozesse gewaltsam beenden (kill, xkill)
Normalerweise läuft ein Prozess bis zum regulären Programmende. Aber leider kommt es auch unter Linux vor, dass Programme Fehler enthalten, sich nicht mehr stoppen lassen und womöglich immer mehr Speicher und CPU-Kapazität beanspruchen. In solchen Fällen muss der Prozess gewaltsam beendet werden. Bei textorientierten Kommandos hilft in den meisten Fällen einfach (Strg)+(C). Damit wird das Programm sofort beendet.
Das Kommando kill versendet Signale an einen laufenden Prozess, der durch die PID-Nummer spezifiziert wird. (Diese Nummer können Sie mit top oder ps ermitteln.) Um ein Programm »höflich« zu beenden, wird das Signal 15 verwendet. (kill verwendet dieses Signal per Default.) Hilft das nicht, muss das Signal 9 eingesetzt werden (hier für den Prozess 2725):
kill kann nur für eigene Prozesse verwendet werden. Nur root darf auch fremde Prozesse beenden.
Auch mit top können Sie Prozesse beenden: Geben Sie einfach (K) und anschließend die Prozessnummer und das gewünschte Signal ein!
killall ist insofern bequemer, als keine Prozessnummer, sondern der Programmname angegeben werden kann. Allerdings werden nun alle Prozesse dieses Namens beendet.
Unter X geht es noch bequemer. Starten Sie in einem Shell-Fenster xkill, und klicken Sie einfach das Fenster des Programms an, das Sie beenden wollen. An den Prozess wird wiederum das Signal 9 gesandt.
Unter KDE können Sie xkill auch mit (Strg)+(Alt)+(Esc) starten. Wenn das irrtümlich passiert, können Sie xkill mit (Esc) abbrechen.
Manchmal wird durch xkill zwar das Fenster geschlossen, der Prozess oder Teile davon laufen aber weiter. Vergewissern Sie sich mit top bzw. mit ps, dass das Programm wirklich beendet ist. Zur Not müssen Sie mit kill -9 n nachhelfen.
Wirklich unangenehm wird es, wenn ein X-Programm nicht nur hängen bleibt, sondern dabei auch den Tastatur- und Maus-Fokus an sich reißt oder X sonstwie blockiert. Der Rechner reagiert dann auf keine Eingaben mehr. In solchen Fällen hilft manchmal die magische Tastenkombination (Strg)+(Alt)+(F1) weiter, mit der der Wechsel in die erste Textkonsole erfolgt. Dort können Sie sich einloggen und das betreffende Programm mit top suchen und beenden.
Wenn die Tastatur vollständig blockiert ist, besteht immer noch die Möglichkeit, sich über ein Netzwerk via ssh einzuloggen und kill auf diese Weise auszuführen. Diese Variante ist natürlich nur möglich, wenn Sie in einem lokalen Netz arbeiten und auf dem lokalen Rechner sshd läuft.
Sollte X selbst nach dem Ende des Programms blockiert bleiben, können Sie versuchen, auch X gewaltsam zu beenden bzw. schließlich shutdown auszuführen. All diese Varianten sind besser als das Drücken der Reset-Taste, was zu Datenverlusten führen kann!
Bei Programmen, die über eine Shell gestartet werden (etwa bei allen Kommandos, die in einem Shell-Fenster ausgeführt werden), können Sie mit dem Shell-Kommando ulimit den maximalen Speicherverbrauch, die maximale Größe erzeugter Dateien etc. begrenzen. ulimit wird üblicherweise in /etc/profile eingestellt.
Verteilung der Rechenzeit (nice, renice, ionice)
Im alltäglichen Betrieb von Linux ist die Rechenkapazität meist mehr als ausreichend, um alle laufenden Prozesse ohne Verzögerungen auszuführen. Wenn Linux aber gerade mit rechenaufwendigen Prozessen beschäftigt ist – z.B. während des Kompilierens eines umfangreichen Programms –, versucht es, die zur Verfügung stehende Rechenzeit gerecht an alle Prozesse zu verteilen.
In manchen Fällen ist es sinnvoll, einem Prozess bewusst mehr oder weniger Rechenzeit zuzuteilen. Dazu dient das Kommando nice, mit dem Programme mit reduzierter oder erhöhter Priorität gestartet werden können. Dazu wird an nice die gewünschte Priorität übergeben, die von 19 (ganz niedrig) bis -20 (ganz hoch) reicht. Per Default werden Prozesse mit der Priorität 0 gestartet. Im folgenden Beispiel wird ein Backup-Programm mit niedrigerer Priorität gestartet, damit es keine anderen Prozesse beeinträchtigt. (Es ist ja egal, ob das Backup ein paar Sekunden länger dauert.)
Mit renice kann auch die Priorität von bereits laufenden Prozessen geändert werden. Als Parameter muss die Prozess-ID angegeben werden, die vorher mit top oder ps ermittelt wurde. Details zu renice finden Sie auf der man-Seite. Auch top ist in der Lage, interaktiv die Priorität eines Prozesses zu verändern; dazu drücken Sie einfach (R). Allerdings kann nur root Programme mit einer höheren Priorität als 0 starten bzw. die Priorität eines bereits laufenden Prozesses erhöhen.
Oft ist nicht die CPU, sondern der Datenträger der limitierende Faktor bei der Ausführung von Programmen. Wenn Sie vermeiden möchten, dass beispielsweise ein Backup-Script die gesamte I/O-Kapazität des Rechners für sich beansprucht und damit andere, vielleicht zeitkritischere Prozesse bremst, können Sie es mit ionice mit reduzierter I/O-Priorität ausführen. Das folgende Kommando liest ein Logical Volume aus, komprimiert seinen Inhalt und speichert ihn in einer Image-Datei:
Ein- und Ausgabeumleitung, Pipe
Fast alle textorientierten Kommandos erwarten Eingaben über den sogenannten Standardeingabekanal (per Default die Tastatur) und senden Ausgaben an den Standardausgabekanal; in einem Terminal wird der resultierende Text einfach angezeigt. Sowohl die Ein- als auch die Ausgabe lassen sich umleiten, wodurch sich viele Möglichkeiten ergeben. Beispielsweise speichert das folgende Kommando die Liste aller Dateien des Verzeichnisses xy in der Datei z:
Durch sogenannte Pipes kann die Ausgabe eines Kommandos als Eingabe für das nächste Kommando verwendet werden. Beim folgenden Beispiel filtert egrep aus der Liste aller installierten Pakete diejenigen heraus, die die Zeichenketten »mysql« oder »mariadb« in beliebiger Groß- und Kleinschreibung enthalten. sort sortiert diese Liste schließlich.
Mit anderen Worten: Die Ausgaben des Kommandos rpm werden dank des ersten |-Zeichens an grep weitergeleitet, dessen Ausgaben mit dem zweiten | -Zeichen an sort. Mehr Details und Beispiele zur Ein- und Ausgabeumleitung finden Sie in Abschnitt 12.4, »Ein- und Ausgabeumleitung«.