Uccidere un processo sospeso?


17

Ero leggermente confuso da:

% vim tmp
zsh: suspended   vim tmp
% kill %1
% jobs
[1]  + suspended   vim tmp
% kill -SIGINT %1
% jobs
[1]  + suspended   vim tmp
% kill -INT %1
% jobs
[1]  + suspended   vim tmp

Quindi mi sono dimesso per "farlo da solo" e mi chiedo perché dopo:

% fg
[1]  - continued   vim tmp
Vim: Caught deadly signal TERM
Vim: Finished.
zsh: terminated   vim tmp
%

Oh!

Ha senso davvero, ora che ci penso, che vimdeve essere in esecuzione per poter dire al suo gestore di segnale di smettere e farlo.

Ma ovviamente non è quello che intendevo.

C'è un modo per "svegliarti e uscire" in un singolo comando? cioè, un alias incorporato per kill %N && fg %N?

Perché il ripristino in background non funziona? Se bginvece di me fg, Vim rimane vivo fino a me fg, che interrompe il mio intuito di cui sopra.

Risposte:


20

vi-vi-viè del diavolo. Devi ucciderlo con il fuoco. Oppure SIGKILL:

kill -KILL %1

Gli built-in killsono abbastanza gentili da inviare SIGCONTa processi sospesi in modo da non doverlo fare da soli, ma ciò non aiuta se il processo blocca il segnale che stai inviando o se la gestione del segnale provoca la sospensione dei processi di nuovo (se un processo in background tenta di leggere dal terminale, per impostazione predefinita, verrà inviato SIGTTIN, il che sospenderà il processo se non gestito).


1
Perché mai dovresti usare SIGABRT? Ha lo scopo di indicare un bug del programma. SIGKILL è qui perché vuoi uccidere il programma ora che lo voglia o no.
Gilles 'SO- smetti di essere malvagio' il

1
In realtà, sembra che SIGTERMora si svegli i processi di sonno, almeno se non hanno gestori per questo. Penso che non funzionasse in questo modo, dal momento che ricordo di dover bgo fgqualcosa prima che potesse ricevere il segnale e andare via. Ma ho provato con awk 'BEGIN{while(42){}}' &, e strace kill $!, e c'è solo una kill(2)chiamata di sistema, con SIGTERM.
Peter Cordes,

6

vimsta installando i gestori di segnale (e probabilmente anche l'impostazione sigprocmask(2)) per ignorare i segnali comuni in modo che tutti i file in fase di modifica non vengano persi a causa di un controllo vagante + c o di un segnale di arresto casuale. Un programma più semplice viene prontamente ucciso:

% cat busyloop.c
int main(void) {
for (;;) { ; }
return 0;
}
% make busyloop
cc     busyloop.c  -o busyloop
% ./busyloop
^Z
zsh: suspended  ./busyloop
% kill %1
%
[1]  + terminated  ./busyloop

Fare vimexit (in modo sicuro) richiederebbe un gestore di segnale vimche accetti TERMo USR1o qualcosa, salvi (o scarti?) Eventuali buffer, ecc. Cosa stai cercando di fare per fare l' vimuscita in questo modo?


"Cosa stai cercando di fare per far uscire Vim in questo modo?" - niente, era un vero file "tmp" che stavo modificando. vimera solo una scelta mal concepita del programma per testare la sospensione.
OJFord,

1
"ignora i segnali comuni in modo che i file in fase di modifica non vadano persi a causa di un controllo randagio + c o di un segnale di fgarresto casuale" - ma non appena ho smesso, si è fermato solo finché è stato sospeso?
OJFord,

2
@OllieFord: SIGKILLsveglia solo un processo di sonno in modo che possa morire. L'invio di segnali a un processo sospeso che ha gestori personalizzati per loro non lo riattiva. (A parte SIGCONTil segnale di continuazione, ovviamente. bgE fginvio SIGCONT.)
Peter Cordes,
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.