Was tun, wenn Strg + C einen Prozess nicht beenden kann?

171

Ctrl+ Cfunktioniert nicht immer, um den aktuellen Prozess abzubrechen (zum Beispiel, wenn dieser Prozess bei bestimmten Netzwerkoperationen beschäftigt ist). In diesem Fall sehen Sie nur "^ C" an Ihrem Cursor und können sonst nicht viel tun.

Was ist der einfachste Weg, um diesen Prozess zum Abbruch zu zwingen, ohne mein Terminal zu verlieren?

Zusammenfassung der Antworten: Normalerweise können Sie Ctrl+ Zden Prozess in den Ruhezustand versetzen und dann tun kill -9 _process-pid_, wo Sie die pid des Prozesses mit ps und anderen Tools finden. Auf Bash (und möglicherweise anderen Shells) können Sie kill -9 %1(oder '% N' im Allgemeinen) das einfacher machen. Wenn Ctrl+ Znicht funktioniert, werden Sie einen anderen Terminal und öffnen Sie müssen töten von dort.

Dustin Boswell
quelle
screenwäre eine mögliche Lösung, mit der Sie ein neues Fenster erstellen und killden Vorgang von dort aus starten können.
Bobby
2
vorausgesetzt, Sie waren bereits in einem Bildschirm :)
Dustin Boswell

Antworten:

119

Um das Problem zu verstehen, warum Ctrl+ Cnicht funktioniert, ist es sehr hilfreich zu verstehen, was passiert, wenn Sie darauf drücken:

Die meisten Schalen binden Ctrl+ Cauf „ein senden SIGINT Signal an das Programm , das zur Zeit im Vordergrund ausgeführt wird “. Über die verschiedenen Signale können Sie per Man-Signal lesen :

 SIGINT        2       Term    Interrupt from keyboard

Programme können dieses Signal ignorieren, da sie auch SIGTSTP ignorieren können :

 SIGTSTP   18,20,24    Stop    Stop typed at tty

(Was ist, was die meisten Muscheln tun, wenn Sie Ctrl+ drücken Z, weshalb es nicht garantiert funktioniert.)

Es gibt einige Signale, die vom Prozess nicht ignoriert werden können: SIGKILL , SIGSTOP und einige andere. Sie können diese Signale über den Befehl kill senden . Um Ihren Prozess des Aufhängens / Zombies zu beenden, suchen Sie einfach die Prozess-ID (PID). Verwenden Sie zum Beispiel pgrepoder psund dann killFolgendes:

 % kill -9 PID
Akira
quelle
13
Eine bloße Bemerkung. Beachten Sie, dass "Zombie" technisch gesehen ein Prozesszustand ist und nicht mit dem übereinstimmt, was Sie hier mit "Zombie" gemeint haben. (Ein abgebrochener Prozess, der nicht von seinem Elternteil gewartet () - wurde, befindet sich im Zombie- ZStatus ( ). In diesem Fall kann er keine Signale mehr verarbeiten.)
Stéphane Gimenez
Leider tun manchmal Strg + C, Strg + Z und Strg + \ nichts, und der Prozess wird ausgeführt, undo sudo (ohne Kennwort zulässig), sodass Sie nicht einfach ein Signal an den Prozess senden können.
Michael
112

Wenn Ctrl+ C(SIGINT) nicht funktioniert, versuchen Sie es mit Ctrl+ \(SIGQUIT). Dann versuchen Sie es mit Ctrl+ Z(SIGTSTP). Wenn Sie zu einer Shell-Eingabeaufforderung zurückkehren, geben Sie killdie Prozess-ID ein. (Dies ist der Standardwert für das SIGTERM-Signal, das Sie mit angeben können kill -TERM. In einigen Shells können Sie möglicherweise %1auf die PID verweisen.) Wenn dies nicht funktioniert, wechseln Sie zu einem anderen Terminal oder einer anderen SSH-Sitzung und führen Sie killoder kill -TERMauf Prozess ID. Dies sollten Sie nur als letzten Ausweg tun kill -KILL, kill -9da es dem Prozess keine Möglichkeit gibt, sauber abzubrechen, seine geöffneten Dateien zu synchronisieren, seine temporären Dateien zu entfernen, Netzwerkverbindungen zu schließen usw.

Teddy
quelle
32

Drücken Sie Strg-Z, um das Programm anzuhalten und in den Hintergrund zu stellen :

Suspend the program currently running and put it in the background.
This does not stop the process as it does in VMS!

(Wiederherstellen in den Vordergrund mit fg)

Dann können Sie killoder kill -9es unter Angabe der Prozess-ID (von der Sie die erhalten ps a).

Daniel Beck
quelle
13
Mit bash können Sie kill $!, ebenso wie $!mit einer speziellen Variablen, die pid des zuletzt hinterlegten Programms enthalten.
Lloeki
@ Loeki Funktioniert bei mir nicht (jedenfalls nicht zuverlässig). Ich muss das erst bgeinmal machen, bevor der Variablen ein Wert zugewiesen wird.
Daniel Beck
2
@ Daniel, richtig. Es ist wie gesagt der letzte Hintergrundprozess , braucht also sozusagen bgdirekt nach Strg + Z nur noch Suspendiert zu werden.
Lloeki
2
Hinweis: Dies ist nicht nur ein Trick, die Verwendung von psoutput (oder killall) ist ziemlich riskant, wenn mehrere Prozesse mit demselben Namen ausgeführt werden. ps -e -o pid,commandliefert pid + full args, nicht nur den Programmnamen, sondern reicht möglicherweise auch nicht aus, um zu unterscheiden. Im Gegensatz dazu $!ist ein sicherer Treffer.
Lloeki
1
@ Loeki Ich bin anderer Meinung. Beispiel einer Ausgabezeile ps aauf meinem System: 27721 s000 T 0:00.09 topWie viele angehaltene ( Tglaube ich) Instanzen desselben Befehls ( top) haben Sie im selben tty ( s000) ausgeführt?
Daniel Beck
30

Siehe auch diesen Link .

Ctrl+ Z: pausiere einen Prozess.

Ctrl+ C: Bitte höflich darum, dass der Prozess jetzt beendet wird.

Ctrl+ \: Beende gnadenlos den Prozess, der gerade im Vordergrund steht

RoboAlex
quelle
"ctrl"+ "\"hat bei mir nicht funktioniert
Benyamin Jafari
13

Normalerweise können Sie den Vorgang immer noch stoppen ( Ctrl+ Z) und dann verwenden kill -9. Dafür kill -9benötigen Sie zuerst die Prozess-PID . Bei Hintergrundjobs kill -9 %1ist dies die einfachste Methode. Wenn Sie sich nicht sicher sind, wie viele Hintergrundjobs Sie beenden möchten, führen Sie sie aus jobs.

Alternativ finden Sie die Prozess-ID mit

ps

Dann kannst du rennen

kill -9 <Appropriate PID from ps output>
Olli
quelle
5

Eine einfachere Lösung für Bash (und andere Shells?) Ist:

Ctrl-z      followed by     kill -9 %1

wobei sich '% 1' auf die Jobnummer bezieht, die getötet wird. Möglicherweise ist es '% 2' (oder etwas anderes), wenn Sie bereits andere Jobs haben, die schlafen. Sie können sehen, um welche Auftragsnummer es sich handelt, wenn Sie Strg-Z drücken:

[1]+  Stopped                 <process name>

Beachten Sie, dass 'kill' die Shell-Version von kill ist, nicht / bin / kill.

Dustin Boswell
quelle
4

1) Wenn Sie sich in der Konsole befinden und sich im Mehrbenutzermodus befinden, können Sie STRG-ALT-Fn drücken und sich auf einem anderen Bildschirm anmelden, ps -ef | grep <myprocessname>oder verwenden pidof <myprocessname>und dann -9 den Prozess anhand der ID-Nummer beenden.

2) Wenn Sie eine Remoteverbindung haben, tun Sie dasselbe über eine andere Terminalsitzung.

Sie können das Leben auch ein wenig erleichtern, indem Sie htop installieren , eine vielseitigere Version von top, mit der Sie laufende Prozesse selektiv beenden können. Die meisten Distributionen haben ein Repo.

3) Wenn Sie sich gerade in einer blockierten SSH-Sitzung befinden (z. B. auf einem anderen System), versuchen Sie, die Escape-Taste Tilde (~) zu drücken, und drücken Sie dann STRG-Z, um zur Host-Sitzung zurückzukehren kann den stecken gebliebenen ssh-prozess beenden oder auf ein Timeout warten, was die meisten nach einer Zeit der Inaktivität tun.

Linker3000
quelle
0

Wenn Sie tmux oder screen verwenden und keines der oben genannten <prefix> xVerfahren funktioniert, können Sie den Bereich trotzdem mit beenden. Der Vorgang wird dann ebenfalls beendet.

ospider
quelle
0

Möglicherweise befindet sich in Ihrem / etc / profile eine mit SIGINT (2) gesetzte Falle. Wenn ja, entfernen Sie es. Melden Sie sich ab und wieder an und Sie sollten gut sein.

TechNo_phile
quelle