Musterbasierter Prozessabbruch in Linux

LinuxBeginner
Jetzt üben

Einführung

In Linux-Systemen ist die effektive Verwaltung von Prozessen für die Aufrechterhaltung der Systemstabilität und -leistung von entscheidender Bedeutung. Während der Befehl kill die Beendigung von Prozessen mithilfe einer bestimmten Prozess-ID (PID) ermöglicht, gibt es Situationen, in denen Sie mehrere Prozesse basierend auf Mustern beenden müssen. Hier kommt der Befehl pkill ins Spiel.

Dieses Lab konzentriert sich auf die Verwendung des Befehls pkill, um Prozesse basierend auf ihren Namen, Argumenten oder anderen Kriterien zu beenden. Sie werden lernen, wie Sie laufende Prozesse identifizieren, sie selektiv mithilfe von Musterabgleich beenden und die Ergebnisse Ihrer Operationen überprüfen können. Diese Fähigkeiten sind für die Systemadministration und das Troubleshooting in Linux-Umgebungen unerlässlich.

Grundlagen der Prozessverwaltung und einfache Prozessbeendigung verstehen

In diesem ersten Schritt werden wir untersuchen, wie man laufende Prozesse identifiziert und mithilfe einfacher Musterabgleiche beendet. Linux bietet mehrere Befehle für die Prozessverwaltung, darunter ps, pgrep und pkill.

Erstellen von Testprozessen

Beginnen wir damit, ein einfaches Skript zu erstellen, das wir als Hintergrundprozess ausführen können. Wir werden mehrere Instanzen dieses Skripts erstellen, um ein Szenario zu simulieren, in dem Sie mehrere ähnliche Prozesse beenden müssen.

Zunächst navigieren Sie in das Projektverzeichnis und erstellen ein Skript namens rogue_app.sh:

cd ~/project
nano rogue_app.sh

Fügen Sie dem Skript den folgenden Inhalt hinzu:

#!/bin/bash
while true; do
  echo "Process running with PID $$"
  sleep 5
done

Dieses Skript führt eine Endlosschleife aus und gibt alle 5 Sekunden seine Prozess-ID (PID) aus.

Machen Sie nun das Skript ausführbar:

chmod +x ~/project/rogue_app.sh

Lassen Sie uns mehrere Instanzen dieses Skripts im Hintergrund ausführen:

for i in {1..5}; do
  ~/project/rogue_app.sh &
done

Das & am Ende des Befehls führt jede Skriptinstanz im Hintergrund aus, sodass Sie weiterhin das Terminal verwenden können.

Anzeigen laufender Prozesse

Um die Prozesse anzuzeigen, die Sie gerade gestartet haben, verwenden Sie den ps-Befehl mit geeigneten Optionen:

ps aux | grep rogue_app.sh

Die Ausgabe sieht in etwa so aus:

labex     12345  0.0  0.0   2308   580 pts/0    S    10:00   0:00 /bin/bash /home/labex/project/rogue_app.sh
labex     12346  0.0  0.0   2308   580 pts/0    S    10:00   0:00 /bin/bash /home/labex/project/rogue_app.sh
labex     12347  0.0  0.0   2308   580 pts/0    S    10:00   0:00 /bin/bash /home/labex/project/rogue_app.sh
labex     12348  0.0  0.0   2308   580 pts/0    S    10:00   0:00 /bin/bash /home/labex/project/rogue_app.sh
labex     12349  0.0  0.0   2308   580 pts/0    S    10:00   0:00 /bin/bash /home/labex/project/rogue_app.sh
labex     12350  0.0  0.0   2432   584 pts/0    S+   10:00   0:00 grep --color=auto rogue_app.sh

Beachten Sie, dass die tatsächlichen PIDs (die Zahlen in der zweiten Spalte) auf Ihrem System unterschiedlich sein werden.

Beenden von Prozessen mit pkill

Nun verwenden wir den pkill-Befehl, um alle Instanzen unseres Skripts zu beenden:

pkill -f rogue_app.sh

Die Option -f teilt pkill mit, gegen die gesamte Befehlszeile zu matchen, nicht nur gegen den Prozessnamen. Dies ist wichtig, da beim Ausführen eines Skripts der Prozessname oft der Interpreter (z. B. /bin/bash) und nicht der Skriptname ist.

Überprüfen Sie, ob alle Instanzen des Skripts beendet wurden:

ps aux | grep rogue_app.sh

Nun sollten Sie in der Ausgabe nur noch den grep-Befehl selbst sehen:

labex     12351  0.0  0.0   2432   584 pts/0    S+   10:01   0:00 grep --color=auto rogue_app.sh

Dies bestätigt, dass alle Instanzen von rogue_app.sh erfolgreich beendet wurden.

Selektive Prozessbeendigung mit Musterabgleich

In realen Szenarien müssen Sie oft selektiver sein, welche Prozesse Sie beenden möchten. Der Befehl pkill ermöglicht es Ihnen, Musterabgleich zu verwenden, um bestimmte Prozesse basierend auf verschiedenen Kriterien anzusteuern.

Erstellen von Prozessen mit unterschiedlichen Argumenten

Erstellen wir ein neues Skript, das wir mit verschiedenen Befehlszeilenargumenten ausführen werden:

cd ~/project
nano service_worker.sh

Fügen Sie dem Skript den folgenden Inhalt hinzu:

#!/bin/bash
while true; do
  echo "Running service worker with argument: $1"
  sleep 5
done

Machen Sie das Skript ausführbar:

chmod +x ~/project/service_worker.sh

Lassen Sie uns nun mehrere Instanzen dieses Skripts mit verschiedenen Argumenten ausführen:

~/project/service_worker.sh normal &
~/project/service_worker.sh normal &
~/project/service_worker.sh --malfunctioning &
~/project/service_worker.sh --malfunctioning &
~/project/service_worker.sh emergency &

Dadurch werden fünf Hintergrundprozesse erstellt: zwei "normale" Worker, zwei "fehlerhafte" Worker und ein "Notfall"-Worker.

Anzeigen von Prozessen mit unterschiedlichen Argumenten

Überprüfen Sie die laufenden Prozesse:

ps aux | grep service_worker.sh

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

labex     12360  0.0  0.0   2308   580 pts/0    S    10:05   0:00 /bin/bash /home/labex/project/service_worker.sh normal
labex     12361  0.0  0.0   2308   580 pts/0    S    10:05   0:00 /bin/bash /home/labex/project/service_worker.sh normal
labex     12362  0.0  0.0   2308   580 pts/0    S    10:05   0:00 /bin/bash /home/labex/project/service_worker.sh --malfunctioning
labex     12363  0.0  0.0   2308   580 pts/0    S    10:05   0:00 /bin/bash /home/labex/project/service_worker.sh --malfunctioning
labex     12364  0.0  0.0   2308   580 pts/0    S    10:05   0:00 /bin/bash /home/labex/project/service_worker.sh emergency
labex     12365  0.0  0.0   2432   584 pts/0    S+   10:05   0:00 grep --color=auto service_worker.sh

Selektive Beendigung mit Musterabgleich

Nun beenden wir selektiv nur die Prozesse mit dem Argument --malfunctioning:

pkill -f "service_worker.sh --malfunctioning"

Die Option -f stellt sicher, dass pkill gegen die gesamte Befehlszeile, einschließlich der Argumente, übereinstimmt.

Überprüfen Sie, ob nur die angestrebten Prozesse beendet wurden:

ps aux | grep service_worker.sh

Sie sollten nun nur die "normalen" und "Notfall"-Prozesse sehen:

labex     12360  0.0  0.0   2308   580 pts/0    S    10:05   0:00 /bin/bash /home/labex/project/service_worker.sh normal
labex     12361  0.0  0.0   2308   580 pts/0    S    10:05   0:00 /bin/bash /home/labex/project/service_worker.sh normal
labex     12364  0.0  0.0   2308   580 pts/0    S    10:05   0:00 /bin/bash /home/labex/project/service_worker.sh emergency
labex     12366  0.0  0.0   2432   584 pts/0    S+   10:06   0:00 grep --color=auto service_worker.sh

Dies zeigt, wie Sie Prozesse basierend auf bestimmten Mustern in ihrer Befehlszeile selektiv beenden können.

Lassen Sie uns nun alle verbleibenden Service-Worker-Prozesse beenden:

pkill -f service_worker.sh

Überprüfen Sie, ob alle Service-Worker-Prozesse beendet wurden:

ps aux | grep service_worker.sh

Sie sollten nun nur den grep-Befehl selbst sehen:

labex     12367  0.0  0.0   2432   584 pts/0    S+   10:07   0:00 grep --color=auto service_worker.sh

Erweiterte Optionen zur Prozessbeendigung

In diesem Schritt untersuchen wir einige erweiterte Optionen des pkill-Befehls, die eine anspruchsvollere Prozessverwaltung ermöglichen.

Verwendung verschiedener Signal-Typen

Standardmäßig sendet pkill das Signal SIGTERM (Signal 15) an Prozesse. Dieses Signal ermöglicht es Prozessen, sich ordnungsgemäß zu beenden, Dateien zu schließen und Aufräumarbeiten durchzuführen. Es gibt jedoch Fälle, in denen Sie ein anderes Signal verwenden möchten.

Erstellen wir ein Skript, das Signale verarbeitet:

cd ~/project
nano signal_handler.sh

Fügen Sie den folgenden Inhalt in das Skript ein:

#!/bin/bash
trap 'echo "Received SIGHUP (1)"; exit 0' SIGHUP
trap 'echo "Received SIGINT (2)"; exit 0' SIGINT
trap 'echo "Received SIGTERM (15)"; exit 0' SIGTERM

echo "Process started with PID $$"
echo "Use: pkill -[signal] -f signal_handler.sh to send signals"
while true; do
  sleep 1
done

Machen Sie das Skript ausführbar:

chmod +x ~/project/signal_handler.sh

Führen Sie das Skript im Hintergrund aus:

~/project/signal_handler.sh &

Nun versuchen wir, verschiedene Signale an den Prozess zu senden:

  1. Senden Sie ein SIGHUP-Signal (Signal 1):
pkill -HUP -f signal_handler.sh
  1. Starten Sie das Skript erneut und senden Sie SIGINT (Signal 2):
~/project/signal_handler.sh &
pkill -INT -f signal_handler.sh
  1. Starten Sie das Skript erneut und senden Sie das Standard-SIGTERM (Signal 15):
~/project/signal_handler.sh &
pkill -f signal_handler.sh ## Default is SIGTERM

Für jedes Signal sollten Sie die entsprechende Meldung in der Terminalausgabe sehen, bevor der Prozess beendet wird.

Beenden von Prozessen nach Alter

pkill ermöglicht es Ihnen, Prozesse basierend auf ihrem Alter über die Option --newest anzusprechen, welche die zuletzt gestarteten Prozesse auswählt.

Erstellen wir einige Prozesse mit unterschiedlichen Startzeiten:

cd ~/project
nano age_test.sh

Fügen Sie den folgenden Inhalt in das Skript ein:

#!/bin/bash
while true; do
  echo "Process running with PID $$"
  sleep 5
done

Machen Sie das Skript ausführbar:

chmod +x ~/project/age_test.sh

Starten Sie den ersten Prozess:

~/project/age_test.sh &

Warten Sie einige Sekunden und starten Sie dann zwei weitere Prozesse:

sleep 5
~/project/age_test.sh &
~/project/age_test.sh &

Nun beenden wir nur die beiden zuletzt gestarteten Prozesse mit der Option --newest:

pkill -f --newest 2 age_test.sh

Überprüfen Sie, welche Prozesse noch laufen:

ps aux | grep age_test.sh

Sie sollten sehen, dass nur der erste Prozess noch läuft, da er vor den anderen beiden Prozessen gestartet wurde.

Beenden Sie den verbleibenden Prozess:

pkill -f age_test.sh

Einschränkung von pkill nach Prozessbesitzer

Sie können die Aktionen von pkill auch auf Prozesse beschränken, die einem bestimmten Benutzer gehören. In einem Multi-User-System ist dies besonders nützlich.

Zur Demonstration führen wir einige Prozesse als der aktuelle Benutzer aus:

~/project/rogue_app.sh &
~/project/rogue_app.sh &

Nun beenden wir diese Prozesse, aber nur diejenigen, die Ihrem aktuellen Benutzer gehören:

pkill -f -u $(whoami) rogue_app.sh

Die Option -u gibt den Benutzernamen des Prozesseigentümers an. Die Befehlssubstitution $(whoami) ruft Ihren aktuellen Benutzernamen ab.

Überprüfen Sie, ob alle Prozesse beendet wurden:

ps aux | grep rogue_app.sh

Sie sollten nur den grep-Befehl selbst in der Ausgabe sehen.

Diese Möglichkeit, Prozesse nach Besitzer gezielt anzusprechen, ist besonders in Multi-User-Umgebungen nützlich, in denen Sie vermeiden möchten, Prozesse anderer Benutzer zu beeinflussen.

Zusammenfassung

In diesem Lab haben Sie gelernt, wie Sie den pkill-Befehl verwenden können, um Prozesse in einer Linux-Umgebung zu verwalten. Dieser leistungsstarke Befehl ermöglicht es Ihnen, Prozesse basierend auf verschiedenen Kriterien zu beenden, was ihn zu einem essentiellen Werkzeug für die Systemadministration macht.

Gedankengänge, die behandelt wurden:

  1. Grundlegende Prozessbeendigung: Sie haben gelernt, wie Sie laufende Prozesse mit dem ps-Befehl identifizieren und sie mit pkill mithilfe eines einfachen Musterabgleichs beenden können.

  2. Selektive Prozessbeendigung: Sie haben untersucht, wie Sie Musterabgleich verwenden können, um Prozesse selektiv anhand ihrer Befehlszeilenargumente anzusteuern, was eine präzise Kontrolle darüber ermöglicht, welche Prozesse beendet werden sollen.

  3. Erweiterte Optionen zur Prozessbeendigung: Sie haben erweiterte Optionen von pkill kennengelernt, darunter:

    • Das Senden unterschiedlicher Signaltypen an Prozesse
    • Das Beenden von Prozessen anhand ihres Alters
    • Die Begrenzung des Anwendungsbereichs von pkill auf Prozesse, die von einem bestimmten Benutzer besessen werden

Diese Fähigkeiten sind wertvoll für die Aufrechterhaltung der Systemstabilität, die Ressourcenverwaltung und die Fehlerbehebung in Linux-Umgebungen. Indem Sie den pkill-Befehl beherrschen, haben Sie ein wichtiges Werkzeug zu Ihrem Linux-Systemadministrationstoolkit hinzugefügt.