Beenden eines Prozesses unter Unix, anstatt ihn zu unterbrechen

12

UnixWenn ich in der Befehlszeile drücke Ctrl-C, wird ein Prozess nicht beendet, sondern unterbrochen, und ich kehre zur Shell-Eingabeaufforderung zurück.

Ich habe also die folgenden zwei Fragen:

    1. Gibt es eine Möglichkeit, die Liste aller unterbrochenen Prozesse anzuzeigen und zu beenden?
    1. Welche Tastenkombination muss gedrückt werden, um einen Prozess zu beenden, anstatt ihn zu unterbrechen?
Nicolás Alarcón Rapela
quelle

Antworten:

20

Ctrl+ Csendet a SIGINT. Standardmäßig wird die Anwendung dadurch beendet.

Sie verwechseln dies mit Ctrl-Z, wodurch eine Anwendung in bash ausgesetzt wird.

Ignacio Vazquez-Abrams
quelle
7

Historisch gesehen waren drei Signale an Tastenanschläge gebunden

  • SIGINT (Interrupt) normalerweise Ctrl+ CoderDel
  • SIGQUIT - Quit - Normalerweise an Ctrl+ gebunden\
  • SIGSUSP Suspend - Normalerweise an Ctrl+ gebundenZ

Bei einigen * nix-Varianten sind auch andere Signale gebunden. Sie können die Tastaturbindungen mit dem Befehl überprüfen

stty -a

Auf meinem System OS / X erzeugt dies die folgende Ausgabe

speed 9600 baud; 65 rows; 213 columns;
lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl
    -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
    -extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8
    -ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
    -dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
    eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
    min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T;
    stop = ^S; susp = ^Z; time = 0; werase = ^W;

Bitte beachten Sie, dass Kill in diesem Fall kein KILL-Signal ist, sondern das Löschen des aktuellen Eingangspuffers.

Möglicherweise haben Sie mehr Erfolg beim Stoppen von Prozessen mit SIGQUIT. Dies ist jedoch möglicherweise nicht der Fall, da der Prozess das Signal möglicherweise abfängt und ignoriert.

Es gibt kein Konzept für eine Liste von "unterbrochenen" Prozessen, da der Prozess den Interrupt entweder abgefangen und ignoriert hat oder beendet wurde. Sie können eine Liste angehaltener Prozesse abrufen, indem Sie Jobs eingeben

Steve Weet
quelle
Es ist interessant, dass ich ^ Q und ^ S zeige (wie Sie), aber so eingestellt habe stty -ixon, dass sie durchlaufen werden. Ich würde denken, dass sie sich ändern würden <undef>.
Bis auf weiteres angehalten.
Ich finde keinen SIGSUSP in den Manpages meiner OS X-Box oder meiner Debian Lenny-Box. Es scheint SIGTSTP zu sein.
dmckee --- Ex-Moderator Kätzchen
DEL - ah, Plan 9 ...
new123456
5

Viele richtige Antworten, aber keine, die vollständig sind.

  1. Wie viele andere bereits gesagt haben: Control-C sendet normalerweise das Unix-Signal SIGINT und das Standardverhalten (von Programmen, die es nicht überschreiben) ist "Prozess beenden". Das Programm kann dieses Signal ignorieren oder auf Wunsch eine andere Aktion ausführen.
  2. Sie können SIGQUIT auch mit Control- \ über die Tastatur senden. Der Unterschied besteht darin, dass der Prozess standardmäßig eine Kerndatei schreibt und dann beendet. Das Programm kann dieses Signal ignorieren oder auf Wunsch eine andere Aktion ausführen.
  3. Um mit extremen Vorurteilen zu beenden und ohne zuzulassen, dass der Prozess gestoppt wird, verwenden Sie SIGKILL, das standardmäßig nicht an einen Schlüssel gebunden ist. Stattdessen senden Sie es normalerweise mit dem kill (1)Befehl und geben das zu sendende Signal wie in an

    $ kill -9 <process ID>
    

    oder mnemonisch

    $ kill -KILL <process ID>
    

    Dieses Signal wird direkt vom Betriebssystem verarbeitet und das Programm kann das Standardverhalten nicht überschreiben.

  4. Wenn Ihre Shell die Jobsteuerung unterstützt, unterstützt sie möglicherweise auch eine integrierte Version, killdie die Jobidentifizierung mithilfe des %Zeichens wie in der Antwort von Catwalk unterstützt .

  5. Um einen Prozess wieder aufzunehmen, verwenden Sie Control-z, das SIGTSTP sendet. Sie setzen einen solchen Prozess fort, indem Sie entweder fgdie Kontrolle über das Terminal behalten oder bges ausführen, ohne die Kontrolle über das Terminal zu behalten (aber standardmäßig immer noch seine Ausgabe dorthin senden).
dmckee --- Ex-Moderator Kätzchen
quelle
Außerdem hängt der Speicherauszug von SIGQUIT von vielen administrativen Details ab. ulimit -c, coreadm (1M) unter Solaris usw. Ein weiterer Hinweis - fg sendet ein SIGCONT-Signal, wodurch der Prozess seinen Betrieb wieder aufnimmt.
Tadeusz A. Kadłubowski
1
  1. um eine Liste der Hintergrundprozesse zu sehen: jobs

    zu töten: kill %1(1 durch entsprechende Job-ID wie in der jobsAusgabe ersetzen )

  2. siehe hier
Gemeinschaft
quelle
1

Strg-C sendet SIGINT, wodurch ein Prozess standardmäßig beendet wird, aber abgefangen werden kann (in \bin sh, using trap).

SIGKILL ist das nicht einfangbare Kill-Signal.

Beim dritten Mal denke ich, dass dies richtig ist: Ich habe alles anhand der Dokumente überprüft. Wir werden sehen.

Charles Stewart
quelle
SIGKILL ist nicht fangbar.
Ja. Ich hatte das schon behoben ...
Charles Stewart
1

Dies ist den meisten Terminal-Neulingen nicht klar, aber wenn Ihr Problem nur darin besteht, dass Sie sich in einem interaktiven Programm befinden und nicht herausfinden können, wie Sie aussteigen sollen, wird es häufig beendet q. Dies ist beispielsweise der Schlüssel zum Beenden. Dies ist unter anderem lessauch das Programm, das Sie beim Anzeigen von manSeiten erhalten.

Einige Programme verfügen über andere Tastaturkürzel zum Beenden. In vimoder viverwenden ESC:wq. In emacsverwenden Control-C Control-X. In nanooder picoverwenden Control-X. Beachten Sie, dass es in diesen Beispielen insbesondere Feinheiten gibt, ob diese Verknüpfungen Änderungen speichern, die Sie möglicherweise an der zu bearbeitenden Datei vorgenommen haben.

asmeurer
quelle
Was ist der Standard?
Pacerier
0

Viele Prozesse können einen Interrupt-Handler installieren, um das Interrupt-Signal abzufangen, aber diejenigen, die nicht standardmäßig abgebrochen werden.

Um das Beenden eines Prozesses zu erzwingen, können Sie SIGQUIT (Ctrl- \) senden.

njd
quelle
SIGQUIT kann gefangen werden, SIGKILL nicht.
Charles Stewart
1
@ Charles: Ein weiterer Unterschied besteht darin, dass SIGQUIT standardmäßig den Core ausgibt, SIGKILL jedoch nicht.
Tadeusz A. Kadłubowski
0

Es scheint, dass die anderen Antworten das wahrscheinliche Szenario sind, aber es ist auch möglich, dass Sie ein Skript ausführen, das seine untergeordneten Elemente nicht richtig behandelt. Ich bin kürzlich auf ein ähnliches Szenario gestoßen, in dem das Beenden eines Skripts die untergeordneten Prozesse dieses Skripts nicht beendet.

Wenn Sie in diese Situation geraten, müssen Sie im Allgemeinen alle von Ihnen ausgeführten Prozesse überprüfen. Sie sollten die Manpage für ps überprüfen. ( man ps) Ich benutze besonders gerne ps auxwf, was die Eltern-Kind-Beziehung zwischen Prozessen zeigt. pstreemacht etwas ähnliches. Sie sollten dies von einem anderen Terminal aus ausführen, bevor Sie den Prozess beenden, um zu sehen, wie die Dinge in der normalen Situation aussehen, und die untergeordneten Prozesse identifizieren.

Wenn Sie diesen Hauptprozess dann (mit ^ C) beenden, überprüfen Sie die Ausgabe von ps erneut, um festzustellen, ob sich etwas geändert hat. Wenn die untergeordneten Prozesse noch vorhanden sind, können Sie sie mit dem killBefehl beenden. (siehe man kill)

BAUM
quelle