Website-Suche

Grundlagen des Prozessmanagements unter Linux


Objektiv

Lernen Sie die Grundlagen des Prozessmanagements unter Linux kennen

Betriebssystem- und Softwareversionen

  • Betriebssystem: – Alle Linux-Distributionen

Anforderungen

  • Einige Programme, die in diesem Tutorial erwähnt werden, benötigen Root-Zugriff

Schwierigkeit

LEICHT

Konventionen

  • # – erfordert, dass bestimmte Linux-Befehle mit Root-Rechten ausgeführt werden, entweder
    direkt als Root-Benutzer oder mit dem Befehl sudo
  • $ – erfordert, dass bestimmte Linux-Befehle als normaler, nicht privilegierter Benutzer ausgeführt werden

Einleitung

Eine der Kernaufgaben eines Systemadministrators besteht darin, die auf einer Maschine ausgeführten Prozesse zu überwachen und mit ihnen zu interagieren. In diesem Tutorial werden Sie in die Verwendung einiger grundlegender Werkzeuge eingeführt, die Ihnen helfen, diese wichtige Aufgabe zu erfüllen.

Der Befehl ps

Ps ist eines der grundlegenden Programme, die in der Prozessüberwachung verwendet werden: Es gibt Ihnen im Grunde einen Snapshot der Prozesse, die auf einer Maschine in dem Moment ausgeführt werden, in dem Sie den Befehl aufrufen. Sehen wir es uns in Aktion an: Zuerst werden wir versuchen, es ohne Optionen auszuführen:

ps

  PID TTY          TIME CMD
24424 pts/0    00:00:00 bash
24468 pts/0    00:00:00 ps

Wie Sie in der obigen Ausgabe sehen können, werden nur zwei Prozesse angezeigt: bash mit einer PID (Prozess-ID) 24424 und ps selbst mit der PID 24468. Dies liegt daran, dass der ps-Befehl, wenn er ohne Option aufgerufen wird, Prozesse anzeigt, die mit der UID des Benutzers, der den Befehl gestartet hat, und dem Terminal, von dem aus er aufgerufen wird, verknüpft sind.

Wie kann man diese Einschränkung überwinden? Mit der Option -a können wir ps so gestalten, dass es uns alle Prozesse anzeigt, mit Ausnahme der Sitzungsleiter und der Prozesse, die nicht mit einem Terminal verbunden sind.

Ein Sitzungsleiter ist ein Prozess, dessen PID mit der SID (Sitzungs-ID) der Sitzung übereinstimmt, in der er (das erste) Mitglied ist. Wenn ein Prozess erstellt wird, wird er Teil derselben Sitzung wie sein übergeordneter Prozess: Da die Sitzungs-ID gemäß der Konvention mit der PID seines ersten Mitglieds identisch ist, nennen wir diesen Prozess einen Sitzungsleiter. Versuchen wir, ps mit der Option -a auszuführen und die Ausgabe zu überprüfen:

ps -a

  PID TTY          TIME CMD
12466 tty1     00:00:00 gnome-session-b
12480 tty1     00:00:17 gnome-shell
12879 tty1     00:00:00 Xwayland
12954 tty1     00:00:00 gsd-sound
12955 tty1     00:00:00 gsd-wacom
12957 tty1     00:00:00 gsd-xsettings
12961 tty1     00:00:00 gsd-a11y-keyboa
12962 tty1     00:00:00 gsd-a11y-settin
12965 tty1     00:00:00 gsd-clipboard
12966 tty1     00:00:03 gsd-color
12967 tty1     00:00:00 gsd-datetime
12970 tty1     00:00:00 gsd-housekeepin
12971 tty1     00:00:00 gsd-keyboard
12972 tty1     00:00:00 gsd-media-keys
12973 tty1     00:00:00 gsd-mouse
12976 tty1     00:00:00 gsd-orientation

[...]

Die Ausgabe des Programms wurde gekürzt, aber man kann leicht erkennen, dass es jetzt Prozesse enthält, die zu verschiedenen Terminals und Benutzern gehören. Die Ausgabe zeigt uns Informationen über PID in der ersten Spalte, TTY in der zweiten, TIME (die kumulative Zeit, die die CPU für den Prozess aufgewendet hat) und CMD (der Befehl, der den Prozess gestartet hat).

Um eine noch umfangreichere Ausgabe zu erhalten, können wir die Optionen -u und -x hinzufügen: Ersteres weist ps an, eine Auswahl nach Benutzer-ID vorzunehmen, während letzteres das Programm anweist, auch Prozesse einzubeziehen, die nicht mit einem Terminal verbunden sind, wie z.B. Daemons:

ps -aux

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.2 223932  8708 ?        Ss   Jul20   0:04 /usr/lib/systemd/systemd --switched-root --system --deserialize 25
root         2  0.0  0.0      0     0 ?        S    Jul20   0:00 [kthreadd]
root         4  0.0  0.0      0     0 ?        S<   Jul20   0:00 [kworker/0:0H]
root         6  0.0  0.0      0     0 ?        S<   Jul20   0:00 [mm_percpu_wq]
root         7  0.0  0.0      0     0 ?        S    Jul20   0:00 [ksoftirqd/0]
root         8  0.0  0.0      0     0 ?        S    Jul20   0:07 [rcu_sched]
root         9  0.0  0.0      0     0 ?        S    Jul20   0:00 [rcu_bh]
root        10  0.0  0.0      0     0 ?        S    Jul20   0:04 [rcuos/0]
root        11  0.0  0.0      0     0 ?        S    Jul20   0:00 [rcuob/0]
root        12  0.0  0.0      0     0 ?        S    Jul20   0:00 [migration/0]
root        13  0.0  0.0      0     0 ?        S    Jul20   0:00 [watchdog/0]
root        14  0.0  0.0      0     0 ?        S    Jul20   0:00 [cpuhp/0]
root        15  0.0  0.0      0     0 ?        S    Jul20   0:00 [cpuhp/1]
root        16  0.0  0.0      0     0 ?        S    Jul20   0:00 [watchdog/1]
root        17  0.0  0.0      0     0 ?        S    Jul20   0:00 [migration/1]
root        18  0.0  0.0      0     0 ?        S    Jul20   0:00 [ksoftirqd/1]
root        20  0.0  0.0      0     0 ?        S<   Jul20   0:00 [kworker/1:0H]
root        21  0.0  0.0      0     0 ?        S    Jul20   0:02 [rcuos/1]
root        22  0.0  0.0      0     0 ?        S    Jul20   0:00 [rcuob/1]
root        23  0.0  0.0      0     0 ?        S    Jul20   0:00 [cpuhp/2]
root        24  0.0  0.0      0     0 ?        S    Jul20   0:00 [watchdog/2]
root        25  0.0  0.0      0     0 ?        S    Jul20   0:00 [migration/2]
root        26  0.0  0.0      0     0 ?        S    Jul20   0:00 [ksoftirqd/2]
root        28  0.0  0.0      0     0 ?        S<   Jul20   0:00 [kworker/2:0H]

[...]
egdoc    13128  0.0  0.1  74736  5388 ?        Ss   Jul20   0:00 /usr/lib/systemd/systemd --user
egdoc    13133  0.0  0.0 106184   420 ?        S    Jul20   0:00 (sd-pam)
egdoc    13143  0.0  0.1 218328  3612 ?        Sl   Jul20   0:00 /usr/bin/gnome-keyring-daemon --daemonize --login

[...]

Sie können sehen, dass eine ganze Reihe neuer Informationen hinzugefügt wurden. Die erste neue Spalte der Ausgabe ist %CPU: Sie zeigt die CPU-Auslastung des Prozesses in Prozent an. Ein Prozentsatz wird auch für die nächste Spalte, %MEM, verwendet, die den physischen Speicher auf dem Computer anzeigt, der vom Prozess verwendet wird. VSZ ist die Größe des virtuellen Speichers des Prozesses, ausgedrückt in KiB.

Die STAT-Spalte verwendet einen Code, um den Prozessstatus auszudrücken. Wir werden hier nicht alle möglichen Zustände beschreiben, sondern nur die erklären, die in der obigen Ausgabe erscheinen (Sie können sich einen vollständigen Überblick verschaffen, indem Sie die ps-Manpage konsultieren).

Betrachten wir den ersten Prozess in der Ausgabe: Er hat PID 1 und ist daher der erste Prozess, der vom Kernel gestartet wird. Das macht Sinn, wir können sehen, dass es sich um systemd handelt, das relativ neue Linux-Init-System, das jetzt von fast allen Distributionen übernommen wird. Zunächst einmal haben wir ein S, das anzeigt, dass sich der Prozess im Zustand des unterbrechbaren Schlafs befindet, was bedeutet, dass er sich im Leerlauf befindet und aufwacht, sobald er eine Eingabe erhält. Das s sagt uns stattdessen, dass es sich bei dem Prozess um einen Sitzungsleiter handelt.

Ein weiteres Symbol, das nicht in der ersten Rohform, sondern in einigen anderen Prozessbeschreibungen erscheint, ist <, das darauf hinweist, dass der Prozess eine hohe Priorität und daher einen niedrigen Nice-Wert hat (was ein Nice-Wert ist, sehen wir im entsprechenden Abschnitt dieses Tutorials). Ein l in der STAT-Spalte gibt an, dass es sich um einen Multithreadprozess handelt, und ein + bedeutet, dass er sich in der Vordergrundprozessgruppe befindet.

In der letzten Spalte befindet sich schließlich die Spalte START, in der der Zeitpunkt angezeigt wird, zu dem der Befehl gestartet wurde.

Eine weitere nette Option, die wir an den ps-Befehl übergeben können, ist -o, die Kurzversion von --format. Mit dieser Option können Sie die Ausgabe mithilfe von Platzhaltern ändern und angeben, welche Spalten angezeigt werden sollen. Führen Sie beispielsweise Folgendes aus:

ps -ax -o %U%p%n%c

Gibt uns zuerst die Spalte USER (%U), gefolgt von der PID des Prozesses (%p), der NI-Spalte (%n), die den Nice-Pegel angibt, und schließlich der Spalte COMMAND (%c):

USER       PID  NI COMMAND
root         1   0 systemd
root         2   0 kthreadd
root         4 -20 kworker/0:0H
root         6 -20 mm_percpu_wq
root         7   0 ksoftirqd/0
root         8   0 rcu_sched
root         9   0 rcu_bh
root        10   0 rcuos/0
root        11   0 rcuob/0
root        12   - migration/0
root        13   - watchdog/0
root        14   0 cpuhp/0
root        15   0 cpuhp/1
root        16   - watchdog/1
root        17   - migration/1
root        18   0 ksoftirqd/1
root        20 -20 kworker/1:0H
root        21   0 rcuos/1
root        22   0 rcuob/1
root        23   0 cpuhp/2
root        24   - watchdog/2
root        25   - migration/2
root        26   0 ksoftirqd/2

Verwendung von "top" zur dynamischen Interaktion mit Prozessen

Während ps uns einen statischen Snapshot der Prozesse und ihrer Informationen zum Zeitpunkt der Ausführung liefert, bietet uns top eine dynamische Ansicht der Prozesse, die in einem bestimmten Zeitintervall aktualisiert wird, das wir sowohl beim Starten des Programms als auch interaktiv angeben können (Standard ist 3 Sekunden).

Top zeigt uns nicht nur eine dynamische Darstellung der laufenden Prozesse: Wir können mit ihnen und mit dem Programm selbst interagieren, indem wir einige Tasten verwenden. Wenn wir zum Beispiel B drücken, können wir die Verwendung von fetten Zeichen umschalten, d lässt uns einen Wert eingeben, um die Verzögerungszeit zu ändern, k ermöglicht es uns, ein Signal an einen Prozess zu senden, indem wir nach seiner PID und dem Signalcode fragen, wobei SIGTERM die Standardeinstellung ist.

Ändern Sie die Priorität von Prozessen mit nice and renice

Wie wir bereits gesehen haben, ist jedem Prozess eine Priorität zugewiesen, die angibt, wie lange der Prozess warten muss, bis andere Prozesse Ressourcen freigeben, bevor er auf diese zugreifen kann. Diese Priorität kann mit einem Wert angegeben werden, der in einem Bereich von -20 bis 19 liegt. Je kleiner der Wert, desto höher ist die Priorität des Prozesses. Das mag auf den ersten Blick kontraintuitiv erscheinen, aber sehen Sie es so: Je schöner der Prozess für andere Prozesse ist, desto mehr werden sie ihn beim Zugriff auf die Ressourcen übertreffen.

Aber wie können wir die Priorität eines Prozesses festlegen? Wir können das schöne Programm verwenden, um die Aufgabe zu erledigen. Angenommen, Sie möchten ein Skript mit dem niedrigstmöglichen Prioritätswert ausführen: Sie würden es folgendermaßen einleiten:

nice -n 19 ./script.sh

Sie können auch die Priorität eines Programms ändern, das bereits läuft, indem Sie renice verwenden, indem Sie seine PID kennen:

renice -n 15 PID

Dabei ist PID die Prozess-ID des Programms. Denken Sie daran, dass der Befehl renice mit Root-Rechten ausgeführt werden muss.

Senden Sie Signale an Prozesse mit den Befehlen kill und killall

Wir können den Befehl kill verwenden, um ein Signal an einen Prozess zu senden, der zu uns gehört, oder an jeden Prozess, wenn wir Root-Rechte haben. Die verschiedenen Signale, die wir senden können, werden durch eine Zahl gekennzeichnet: Wir können diese Entsprechungen leicht erkennen, indem wir den Befehl kill mit der Option -l ausführen:

kill -l
1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX

Wenn dem Befehl kill keine Option übergeben wird, sendet er standardmäßig ein SIGTERM-Signal an den angegebenen Prozess, auf den dieser auf verschiedene Weise reagieren kann: Er kann sofort stoppen, versuchen, vor dem Stopp etwas aufzuräumen, oder das Signal einfach ignorieren.

Um das zu sendende Signal mit kill anzugeben, führen wir den Befehl gefolgt von einem Bindestrich und der Nummer des zu sendenden Signals aus. Um beispielsweise ein SIGKILL-Signal auszuführen, sollten wir Folgendes ausführen:

kill -9 PID

Das SIGKILL-Signal kann im Gegensatz zu SIGTERM nicht von dem Prozess abgefangen werden, der nicht reagieren kann: Es wird einfach sofort beendet.

Ein weiteres Signal, das Sie häufig sehen werden, ist SIGINT, das Signal, das über einen Tastatur-Interrupt (STRG-c) gesendet wird. Es versucht auch, den Prozess auf ordnungsgemäße Weise zu beenden, und kann vom Prozess ignoriert werden. SIGSTOP und SIGCONT unterbrechen bzw. setzen die Ausführung eines Prozesses fort: Ersteres kann, wie SIGKILL, nicht abgefangen oder ignoriert werden. Für eine vollständige Liste und Beschreibung der Signale können Sie das Handbuch für signal(7) konsultieren:

man 7 signal

Das killall-Programm hat den gleichen Zweck wie kill und sendet wie kill ein SIGTERM-Signal, wenn kein anderes angegeben ist (diesmal mit der Option --signal), aber anstatt einen Prozess anhand seiner PID zu referenzieren, wird es dies über den Befehlsnamen tun, wodurch effektiv alle Prozesse getötet werden, die unter demselben ausgeführt werden.

Verwandte Artikel: