Verwendung der Jobsteuerung von Bash zum Verwalten von Vordergrund- und Hintergrundprozessen

Einführung

In diesem Handbuch wird erläutert, wiebash, das Linux-System und Ihr Terminal zusammenkommen, um Prozess- und Jobsteuerung zu bieten. Inprevious guide haben wir erläutert, wie die Befehleps,kill undnice zur Steuerung von Prozessen auf Ihrem System verwendet werden können.

Dieser Artikel konzentriert sich auf die Verwaltung von Vordergrund- und Hintergrundprozessen und zeigt, wie Sie die Jobsteuerungsfunktionen Ihrer Shell nutzen können, um mehr Flexibilität bei der Ausführung von Befehlen zu erhalten.

Vordergrundprozesse verwalten

Die meisten Prozesse, die Sie auf einem Linux-Computer starten, werden im Vordergrund ausgeführt. Der Befehl wird ausgeführt und blockiert die Verwendung der Shell für die Dauer des Prozesses. Der Prozess kann eine Benutzerinteraktion ermöglichen oder nur eine Prozedur durchlaufen und dann beendet werden. Alle Ausgaben werden standardmäßig im Terminalfenster angezeigt. Im Folgenden wird die grundlegende Vorgehensweise zum Verwalten von Vordergrundprozessen erläutert.

Prozess starten

Standardmäßig werden Prozesse im Vordergrund gestartet. Solange das Programm nicht beendet wird oder sich nicht ändert, können Sie nicht mit der Shell interagieren.

Einige Vordergrundbefehle werden sehr schnell beendet und führen Sie fast sofort zu einer Shell-Eingabeaufforderung zurück. Zum Beispiel dieser Befehl:

echo "Hello World"

Dadurch wird "Hello World" auf dem Terminal ausgegeben und Sie kehren zur Eingabeaufforderung zurück.

Die Ausführung anderer Vordergrundbefehle dauert länger und blockiert den Shell-Zugriff für die Dauer. Dies kann daran liegen, dass der Befehl eine umfangreichere Operation ausführt oder so konfiguriert ist, dass er ausgeführt wird, bis er explizit gestoppt wird oder bis er andere Benutzereingaben empfängt.

Ein Befehl, der auf unbestimmte Zeit ausgeführt wird, ist das Dienstprogrammtop. Nach dem Start wird die Anzeige so lange ausgeführt und aktualisiert, bis der Benutzer den Vorgang beendet:

top

Sie können den Vorgang beenden, indem Sie "q" eingeben. Einige Prozesse haben keine dedizierte Beendigungsfunktion. Um diese zu stoppen, müssen Sie eine andere Methode anwenden.

Prozess beenden

Angenommen, wir starten eine einfachebash-Schleife in der Befehlszeile. Wir können eine Schleife starten, die alle zehn Sekunden "Hello World" ausgibt. Diese Schleife wird für immer fortgesetzt, bis sie explizit beendet wird:

while true; do echo "Hello World"; sleep 10; done

Loops haben keine Quit-Taste. Wir müssen den Prozess stoppen, indem wir ihmsignal senden. Unter Linux kann der Kernel Prozesssignale senden, um anzufordern, dass sie beendet werden oder den Status ändern. Linux-Terminals sind normalerweise so konfiguriert, dass sie das Signal „SIGINT“ (normalerweise Signal Nummer 2) an den aktuellen Vordergrundprozess senden, wenn die TastenkombinationCTRL-Cgedrückt wird. Das SIGINT-Signal teilt dem Programm mit, dass der Benutzer die Beendigung über die Tastatur angefordert hat.

Um die von uns gestartete Schleife zu stoppen, halten Sie die Steuertaste gedrückt und drücken Sie die Taste "c":

CTRL-C

Die Schleife wird beendet und die Steuerung an die Shell zurückgegeben.

Das von derCTRL-C-Kombination gesendete SIGINT-Signal ist eines von vielen Signalen, die an Programme gesendet werden können. Den meisten Signalen sind keine Tastaturkombinationen zugeordnet, und sie müssen stattdessen mit dem Befehlkill gesendet werden (wir werden dies später behandeln).

Prozesse anhalten

Wir haben oben erwähnt, dass der Vordergrundprozess den Zugriff auf die Shell für die Dauer ihrer Ausführung blockiert. Was ist, wenn wir einen Prozess im Vordergrund starten und dann feststellen, dass wir Zugriff auf das Terminal benötigen?

Ein weiteres Signal, das wir senden können, ist das Signal „SIGTSTP“ (normalerweise Signal Nummer 20). Wenn wirCTRL-Z drücken, registriert unser Terminal einen "Suspend" -Befehl, der dann das SIGTSTP-Signal an den Vordergrundprozess sendet. Dies unterbricht im Wesentlichen die Ausführung des Befehls und gibt die Steuerung an das Terminal zurück.

Verwenden Sie zur Demonstrationping, um alle 5 Sekunden eine Verbindung zu google.com herzustellen. Wir werden dem Befehlpingcommand voranstellen, wodurch wir alle Shell-Aliase umgehen können, die künstlich eine maximale Anzahl für den Befehl festlegen:

command ping -i 5 google.com

Anstatt den Befehl mitCTRL-C zu beenden, geben Sie stattdessenCTRL-Z ein:

CTRL-Z

Sie werden eine Ausgabe sehen, die so aussieht:

Output[1]+  Stopped                 ping -i 5 google.com

Der Befehlping wurde vorübergehend gestoppt, sodass Sie erneut auf eine Shell-Eingabeaufforderung zugreifen können. Wir können das Prozesstoolpsverwenden, um dies zu zeigen:

ps T
Output  PID TTY      STAT   TIME COMMAND
26904 pts/3    Ss     0:00 /bin/bash
29633 pts/3    T      0:00 ping -i 5 google.com
29643 pts/3    R+     0:00 ps t

Wir können sehen, dass der Prozess vonpingimmer noch aufgelistet ist, aber dass die Spalte "STAT" ein "T" enthält. Die Manpage vonpsgibt an, dass dies ein Job ist, der „durch (a) Jobsteuersignal gestoppt“ wurde.

Wir werden uns eingehender mit dem Ändern von Prozesszuständen befassen, können die Ausführung des Befehls jedoch vorerst wieder im Vordergrund fortsetzen, indem wir Folgendes eingeben:

fg

Wenn der Prozess fortgesetzt wurde, beenden Sie ihn mitCTRL-C:

CTRL-C

Hintergrundprozesse verwalten

Die Hauptalternative zum Ausführen eines Prozesses im Vordergrund besteht darin, ihn im Hintergrund ausführen zu lassen. Ein Hintergrundprozess ist dem spezifischen Terminal zugeordnet, von dem er gestartet wurde, blockiert jedoch nicht den Zugriff auf die Shell. Stattdessen wird es im Hintergrund ausgeführt, sodass der Benutzer während der Ausführung des Befehls mit dem System interagieren kann.

Aufgrund der Art und Weise, wie ein Vordergrundprozess mit seinem Terminal interagiert, kann es für jedes Terminalfenster nur einen einzelnen Vordergrundprozess geben. Da Hintergrundprozesse die Steuerung sofort an die Shell zurückgeben, ohne auf den Abschluss des Prozesses zu warten, können viele Hintergrundprozesse gleichzeitig ausgeführt werden.

Prozesse starten

Sie können einen Hintergrundprozess starten, indem Sie ein kaufmännisches Und-Zeichen ("&") an das Ende Ihrer Befehle anhängen. Dadurch wird die Shell angewiesen, nicht auf den Abschluss des Prozesses zu warten, sondern mit der Ausführung zu beginnen und den Benutzer sofort zu einer Eingabeaufforderung zurückzukehren. Die Ausgabe des Befehls wird weiterhin im Terminal angezeigt (außerredirected). Sie können jedoch zusätzliche Befehle eingeben, während der Hintergrundprozess fortgesetzt wird.

Zum Beispiel können wir den gleichen Ping-Prozess ab dem letzten Abschnitt im Hintergrund starten, indem wir Folgendes eingeben:

command ping -i 5 google.com &

Sie sehen eine Ausgabe des Jobsteuerungssystems vonbash, die folgendermaßen aussieht:

Output[1] 4287

Sie sehen auch die normale Ausgabe des Befehlsping:

OutputPING google.com (74.125.226.71) 56(84) bytes of data.
64 bytes from lga15s44-in-f7.1e100.net (74.125.226.71): icmp_seq=1 ttl=55 time=12.3 ms
64 bytes from lga15s44-in-f7.1e100.net (74.125.226.71): icmp_seq=2 ttl=55 time=11.1 ms
64 bytes from lga15s44-in-f7.1e100.net (74.125.226.71): icmp_seq=3 ttl=55 time=9.98 ms

Sie können jedoch auch gleichzeitig Befehle eingeben. Die Ausgabe des Hintergrundprozesses wird mit der Eingabe und Ausgabe Ihrer Vordergrundprozesse gemischt, beeinträchtigt jedoch nicht die Ausführung der Vordergrundprozesse.

Hintergrundprozesse auflisten

Um alle gestoppten oder im Hintergrund befindlichen Prozesse anzuzeigen, können Sie den Befehljobs verwenden:

jobs

Wenn der Befehlping im Hintergrund ausgeführt wird, wird Folgendes angezeigt:

Output[1]+  Running                 command ping -i 5 google.com &

Dies zeigt, dass derzeit ein einzelner Hintergrundprozess ausgeführt wird. Das[1] repräsentiert die "Jobspezifikation" oder Jobnummer des Befehls. Wir können dies mit anderen Job- und Prozesssteuerungsbefehlen wiekill,fg undbg referenzieren, indem wir der Jobnummer ein Prozentzeichen voranstellen. In diesem Fall würden wir diesen Job als%1 bezeichnen.

Hintergrundprozesse stoppen

Wir können den aktuellen Hintergrundprozess auf verschiedene Arten stoppen. Am einfachsten ist es, den Befehlkill mit der zugehörigen Jobnummer zu verwenden. Zum Beispiel können wir unseren laufenden Hintergrundprozess beenden, indem wir Folgendes eingeben:

kill %1

Abhängig davon, wie Ihr Terminal konfiguriert ist, sehen Sie entweder sofort oder beim nächsten Drücken der EINGABETASTE den Status der Jobbeendigung:

Output[1]+  Terminated              command ping -i 5 google.com

Wenn wir den Befehljobs erneut überprüfen, werden keine aktuellen Jobs angezeigt.

Prozesszustände ändern

Nachdem wir wissen, wie Prozesse im Hintergrund gestartet und gestoppt werden, können wir über das Ändern ihres Status sprechen.

Wir haben zuvor eine Zustandsänderung demonstriert, als wir beschrieben haben, wie ein Prozess mitCTRL-Z gestoppt oder angehalten werden kann. Wenn sich Prozesse in diesem angehaltenen Zustand befinden, können wir einen Vordergrundprozess in den Hintergrund verschieben oder umgekehrt.

Verschieben von Vordergrundprozessen in den Hintergrund

Wenn wir vergessen, einen Befehl beim Start mit& zu beenden, können wir den Prozess trotzdem in den Hintergrund verschieben.

Der erste Schritt besteht darin, den Prozess erneut mitCTRL-Z zu stoppen:

CTRL-Z

Sobald der Prozess gestoppt ist, können wir ihn mit dem Befehlbg im Hintergrund erneut starten:

bg

Die Auftragsstatuszeile wird erneut angezeigt, diesmal mit dem angehängten kaufmännischen Und:

Output[1]+ ping -i 5 google.com &

Standardmäßig wird der Befehlbg mit dem zuletzt gestoppten Prozess ausgeführt. Wenn Sie mehrere Prozesse hintereinander gestoppt haben, ohne sie erneut zu starten, können Sie den Prozess anhand der Jobnummer referenzieren, um den korrekten Prozess im Hintergrund anzuzeigen.

Beachten Sie, dass nicht alle Befehle im Hintergrund ausgeführt werden können. Einige Prozesse werden automatisch beendet, wenn sie feststellen, dass ihre Standardeingabe und -ausgabe direkt mit einem aktiven Terminal verbunden sind.

Hintergrundprozesse in den Vordergrund rücken

Wir können Hintergrundprozesse auch in den Vordergrund rücken, indem wirfg eingeben:

fg

Dies funktioniert auf Ihrem zuletzt hinterlegten Prozess (angezeigt durch das "" in der Ausgabe "+ Jobs"). Es unterbricht den Vorgang sofort und stellt ihn in den Vordergrund. Verwenden Sie die Auftragsnummer, um einen anderen Auftrag anzugeben:

fg %2

Sobald ein Job im Vordergrund steht, können Sie ihn mitCTRL-C beenden, ihn abschließen lassen oder ihn anhalten und erneut in den Hintergrund stellen.

Mit SIGHUPs umgehen

Unabhängig davon, ob sich ein Prozess im Hintergrund oder im Vordergrund befindet, ist er eng mit der Terminalinstanz verknüpft, von der er gestartet wurde. Wenn ein Terminal geschlossen wird, sendet es normalerweise ein SIGHUP-Signal an alle Prozesse (Vordergrund, Hintergrund oder gestoppt), die mit dem Terminal verbunden sind. Dies signalisiert, dass die Prozesse beendet werden, da ihr steuerndes Terminal in Kürze nicht verfügbar sein wird. Was ist, wenn Sie ein Terminal schließen und die Hintergrundprozesse weiterhin ausführen möchten?

Es gibt eine Reihe von Möglichkeiten, dies zu erreichen. Die flexibelsten Möglichkeiten bestehen normalerweise darin, einen Terminal-Multiplexer wiescreen odertmux zu verwenden oder ein Dienstprogramm zu verwenden, das zumindest die Trennfunktionalität dieser Funktionen wiedtach bietet.

Dies ist jedoch nicht immer eine Option. Manchmal sind diese Programme nicht verfügbar oder Sie haben bereits den Prozess gestartet, den Sie für die weitere Ausführung benötigen. Manchmal sind diese übertrieben für das, was Sie erreichen müssen.

Mit nohup

Wenn Sie beim Starten des Prozesses wissen, dass Sie das Terminal schließen möchten, bevor der Prozess abgeschlossen ist, können Sie es mit dem Befehlnohup starten. Dies macht den gestarteten Prozess immun gegen das SIGHUP-Signal. Sie läuft weiter, wenn das Terminal geschlossen wird. Es wird als untergeordnetes Element des Init-Systems neu zugewiesen:

nohup ping -i 5 google.com &

Sie sehen eine Zeile, die so aussieht und angibt, dass die Ausgabe des Befehls in eine Datei mit dem Namennohup.out geschrieben wird (im aktuellen Verzeichnis, falls beschreibbar, andernfalls in Ihr Ausgangsverzeichnis):

Outputnohup: ignoring input and appending output to ‘nohup.out’

Dadurch wird sichergestellt, dass die Ausgabe nicht verloren geht, wenn das Terminalfenster geschlossen wird.

Wenn Sie das Terminalfenster schließen und ein anderes öffnen, wird der Prozess weiterhin ausgeführt. Sie werden es nicht in der Ausgabe des Befehlsjobs sehen, da jede Terminalinstanz ihre eigene unabhängige Jobwarteschlange verwaltet. Durch das Schließen des Terminals wurdenpingjob zerstört, obwohlpingprocess noch ausgeführt wird.

Um den Prozess vonpingabzubrechen, müssen Sie seine Prozess-ID (oder "PID") nachschlagen. Sie können dies mit dem Befehlpgrep tun (es gibt auch einen Befehlpkill, aber diese zweiteilige Methode stellt sicher, dass nur der beabsichtigte Prozess beendet wird). Verwenden Siepgrep und das Flag-a, um nach der ausführbaren Datei zu suchen:

pgrep -a ping
Output7360 ping -i 5 google.com

Sie können den Vorgang dann abbrechen, indem Sie auf die zurückgegebene PID verweisen. Dies ist die Nummer in der ersten Spalte:

kill 7360

Möglicherweise möchten Sie die Dateinohup.outentfernen, wenn Sie sie nicht mehr benötigen.

Disown verwenden

Der Befehlnohup ist hilfreich, aber nur, wenn Sie wissen, dass Sie ihn zum Zeitpunkt des Starts des Prozesses benötigen. Das Jobsteuerungssystem vonbashbietet andere Methoden, um ähnliche Ergebnisse mit dem integrierten Befehldisownzu erzielen.

Der Befehldisown entfernt in seiner Standardkonfiguration einen Job aus der Jobwarteschlange eines Terminals. Dies bedeutet, dass es nicht mehr mit den in diesem Handbuch beschriebenen Jobsteuerungsmechanismen verwaltet werden kann (wiefg,bg,CTRL-Z,CTRL-C). Es wird sofort aus der Liste in der Ausgabe vonjobsentfernt und ist nicht mehr dem Terminal zugeordnet.

Der Befehl wird durch Angabe einer Auftragsnummer aufgerufen. Um beispielsweise Job 2 sofort abzulehnen, könnten wir Folgendes eingeben:

disown %2

Dadurch bleibt der Prozess in einem Zustand, der dem einesnohup-Prozesses nach dem Schließen des Steuerterminals nicht unähnlich ist. Die Ausnahme ist, dass alle Ausgaben verloren gehen, wenn das steuernde Terminal geschlossen wird, wenn es nicht in eine Datei umgeleitet wird.

Normalerweise möchten Sie den Prozess nicht vollständig aus der Jobsteuerung entfernen, wenn Sie Ihr Terminalfenster nicht sofort schließen. Sie können stattdessen das-h-Flag an dendisown-Prozess übergeben, um den Prozess zu markieren, um SIGHUP-Signale zu ignorieren, aber ansonsten als regulärer Job fortzufahren:

disown -h %1

In diesem Zustand können Sie normale Jobsteuerungsmechanismen verwenden, um den Prozess weiter zu steuern, bis das Terminal geschlossen wird. Wenn Sie das Terminal schließen, werden Sie wieder bei einem Prozess stecken bleiben, bei dem keine Ausgabe möglich ist, wenn Sie beim Starten nicht zu einer Datei umgeleitet haben.

Um dies zu umgehen, können Sie versuchen, die Ausgabe Ihres Prozesses umzuleiten, nachdem er bereits ausgeführt wird. Dies liegt außerhalb des Geltungsbereichs dieses Handbuchs. Sie können sich jedochthis post ansehen, um eine Vorstellung davon zu erhalten, wie Sie dies tun würden.

Verwendung der huponexit Shell Option

Bash hat auch eine andere Möglichkeit, das SIGHUP-Problem für untergeordnete Prozesse zu vermeiden. Die Shell-Optionhuponexitteuert, ob bash seine untergeordneten Prozesse sendet, verarbeitet das SIGHUP-Signal beim Beenden.

Note

[.Hinweis]##

Die Optionhuponexit wirkt sich nur auf das SIGHUP-Verhalten aus, wenn eine Shell-Sitzungsbeendigungfrom within the shell itself eingeleitet wird. Einige Beispiele dafür, wann dies zutrifft, sind, wenn der Befehlexit oderCTRL-D innerhalb der Sitzung getroffen wird.

Wenn eine Shell-Sitzung über das Terminalprogramm selbst beendet wird (durch Schließen des Fensters usw.), wirkt sich der Befehlhuponexit aufnoaus. Anstattbash zu entscheiden, ob das SIGHUP-Signal gesendet werden soll, sendet das Terminal selbst das SIGHUP-Signal anbash, das das Signal dann (korrekt) an seine untergeordneten Prozesse weitergibt.

Trotz der oben genannten Einschränkungen ist die Optionhuponexitmöglicherweise eine der einfachsten. Sie können feststellen, ob diese Funktion aktiviert oder deaktiviert ist, indem Sie Folgendes eingeben:

shopt huponexit

Geben Sie zum Einschalten Folgendes ein:

shopt -s huponexit

Wenn Sie Ihre Sitzung jetzt durch Eingabe vonexit beenden, werden Ihre Prozesse weiterhin ausgeführt:

exit

Dies hat die gleichen Einschränkungen hinsichtlich der Programmausgabe wie die letzte Option. Stellen Sie daher sicher, dass Sie die Ausgabe Ihrer Prozesse umgeleitet haben, wenn dies vor dem Schließen des Terminals wichtig ist.

Fazit

Das Erlernen der Jobsteuerung und das Verwalten von Vordergrund- und Hintergrundprozessen bieten Ihnen mehr Flexibilität beim Ausführen von Programmen über die Befehlszeile. Anstatt viele Terminalfenster oder SSH-Sitzungen öffnen zu müssen, können Sie häufig mit ein paar Stopp- und Hintergrundbefehlen auskommen.