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 Befehlsudo - $ – 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.shSie 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 PIDDabei 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 PIDDas 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 signalDas 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.
