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-C
gedrü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 Befehlping
command
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 Prozesstoolps
verwenden, 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 vonping
immer noch aufgelistet ist, aber dass die Spalte "STAT" ein "T" enthält. Die Manpage vonps
gibt 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 wurdenping
job zerstört, obwohlping
process noch ausgeführt wird.
Um den Prozess vonping
abzubrechen, 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.out
entfernen, 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 vonbash
bietet andere Methoden, um ähnliche Ergebnisse mit dem integrierten Befehldisown
zu 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 vonjobs
entfernt 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-Optionhuponexit
teuert, 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 Optionhuponexit
mö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.