Termina un processo in Unix invece di interromperlo


12

Alla Unixriga di comando se premo Ctrl-C, questo non termina un processo, ma piuttosto lo interrompe e torno al prompt della shell.

Quindi, ho le seguenti due domande:

    1. C'è un modo per vedere l'elenco di tutti i processi interrotti e terminarli?
    1. Quale combinazione di tasti premere per terminare un processo invece di interromperlo?

Risposte:


20

Ctrl+ Cinvia a SIGINT. Di default questo termina l'applicazione.

Stai confondendo questo con Ctrl-Z, che sospende un'applicazione in bash.


7

Storicamente c'erano tre segnali associati a sequenze di tasti

  • SIGINT (Intettput) di solito Ctrl+ CoDel
  • SIGQUIT - Esci - Di solito associato a Ctrl+\
  • SIGSUSP Suspend - Di solito associato a Ctrl+Z

Su alcuni tipi di * nix ci sono anche altri segnali associati, puoi controllare i collegamenti della tastiera usando il comando

stty -a

Sul mio sistema, OS / X, questo produce il seguente output

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;

Si noti che kill in questo caso non è un segnale KILL che ha a che fare con la cancellazione del buffer di input corrente.

Potresti avere più successo con l'arresto dei processi usando SIGQUIT, ma questo potrebbe non essere vero poiché il processo potrebbe catturare il segnale e ignorarlo.

Non esiste un concetto di un elenco di processi "interrotti" poiché il processo ha catturato e ignorato l'interruzione o è uscito. È possibile ottenere un elenco di processi sospesi digitando lavori


È interessante che io abbia mostrato ^ Q e ^ S (come te) ma ho impostato in stty -ixonmodo che siano passati. Penserei che sarebbero cambiati in <undef>.
In pausa fino a ulteriore avviso.

Non trovo SIGSUSP nelle pagine man del mio box OS X o del mio box Debian Lenny. Sembra essere SIGTSTP.
dmckee --- ex-moderatore gattino

DEL - ah, Plan 9 ...
new123456

5

Molte risposte corrette, ma nessuna completa.

  1. Come molti altri hanno detto: Control-C in genere invia il segnale unix SIGINT e il comportamento predefinito (dai programmi che non lo sovrascrivono) è "termina processo". Il programma può ignorare questo segnale o intraprendere un'azione diversa se lo desidera.
  2. Puoi anche inviare SIGQUIT dalla tastiera con Control- \. La differenza qui è che per impostazione predefinita il processo scriverà un file core, quindi verrà chiuso. Il programma può ignorare questo segnale o intraprendere un'azione diversa se lo desidera.
  3. Per terminare con estremo pregiudizio e senza interrompere il processo, utilizzare SIGKILL, che per impostazione predefinita non è associato a nessuna chiave. Invece generalmente lo si invia usando il kill (1)comando e specificando il segnale da inviare come in

    $ kill -9 <process ID>
    

    o mnemonicamente

    $ kill -KILL <process ID>
    

    Questo segnale viene gestito direttamente dal sistema operativo e il programma non può ignorare il comportamento predefinito.

  4. Se la tua shell supporta il controllo del lavoro, può anche supportare una versione integrata killche supporta l'identificazione del lavoro usando il %personaggio come nella risposta della passerella .

  5. Per mettere in pausa un processo in modo ripristinabile si utilizza Control-z che invia SIGTSTP. Si riprende tale processo con o fgper continuare a controllare il terminale o bgper impostarlo in esecuzione senza mantenere il controllo del terminale (ma, per impostazione predefinita, inviando ancora l'output lì).

Inoltre, il core di dumping su SIGQUIT dipende da molti dettagli amministrativi. ulimit -c, coreadm (1M) su Solaris ecc. Un'altra nota - fg invia il segnale SIGCONT, che fa riprendere il processo al processo.
Tadeusz A. Kadłubowski,

1
  1. per vedere l'elenco dei processi in background: jobs

    uccidere: kill %1(sostituire 1 con ID lavoro corrispondente come jobsnell'output)

  2. vedi qui

1

Ctrl-C invia SIGINT, che di default provoca la fine di un processo, ma può essere intrappolato (dentro \bin sh, usando trap).

SIGKILL è il segnale di uccisione inarrestabile.

Modifica Terza volta, penso che sia giusto: ho controllato tutto con i documenti. Vedremo.


SIGKILL non è intercettabile.

Sì. Avevo già risolto questo ...
Charles Stewart il

1

Questo non è chiaro per la maggior parte dei neofiti del terminale, ma se il tuo problema è solo che sei in un programma interattivo e non riesci a capire come uscire, abbastanza spesso quscirà. Ad esempio, questa è la chiave per uscire less, che è anche il programma che si ottiene quando si visualizzano le manpagine, tra le altre cose.

Alcuni programmi hanno altre scorciatoie da tastiera per uscire. In vimo vi, utilizzare ESC:wq. In emacs, utilizzare Control-C Control-X. In nanoo pico, utilizzare Control-X. Si noti che in questi esempi ci sono delle sottigliezze, in particolare, relative al fatto che tali scorciatoie salvino o meno tutte le modifiche che è possibile aver apportato al file che si sta modificando.


Quindi qual è lo standard?
Pacerier,

0

Molti processi possono installare un gestore di interrupt per catturare il segnale di interruzione, ma quelli che non si interrompono per impostazione predefinita.

Per forzare la chiusura di un processo, è possibile inviare SIGQUIT (Ctrl- \).


SIGQUIT può essere intrappolato, SIGKILL non può essere.
Charles Stewart,

1
@Charles: un'altra differenza è che SIGQUIT esegue il dump del core di default, SIGKILL no.
Tadeusz A. Kadłubowski,

0

Sembra che le altre risposte siano lo scenario probabile, ma è anche possibile che tu stia eseguendo uno script che non gestisce correttamente i suoi figli. Recentemente ho colpito uno scenario simile, in cui uccidere una sceneggiatura non ucciderebbe i processi figlio di quella sceneggiatura.

In generale, se ti imbatti in questa situazione, dovrai rivedere tutti i processi che stai eseguendo. Dovresti rivedere la manpage di ps. ( man ps) Mi piace particolarmente usare ps auxwf, che mostra la relazione genitore / figlio tra i processi. pstreefa qualcosa di simile. Dovresti eseguirlo da un altro terminale prima di uccidere il processo per vedere come appaiono le cose nella situazione normale e identificare i processi figlio.

Se poi uccidi (con ^ C) quel processo principale, controlla di nuovo l'output di ps per vedere se qualcosa è cambiato. Se i processi figlio sono ancora presenti, è possibile ucciderli con il killcomando. (vedi man kill)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.