¿Matar un proceso suspendido?

17

Estaba un poco confundido por:

% 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

Así que renuncié a "hacerlo yo mismo" y me pregunto por qué más tarde:

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

Oh!

Tiene sentido realmente, ahora que lo pienso, eso vimtiene que estar ejecutándose para que se le diga a su manejador de señales que abandone, y que lo haga.

Pero obviamente no es lo que pretendía.

¿Hay alguna manera de "despertar y salir" en un solo comando? es decir, un alias incorporado para kill %N && fg %N?

¿Por qué no funciona reanudar en segundo plano? Si yo en bglugar de fg, Vim permanece vivo hasta que yo fg, lo que rompe mi intuición anterior.

OJFord
fuente

Respuestas:

20

vi-vi-viEs del diablo. Debes matarlo con fuego. O SIGKILL:

kill -KILL %1

Los componentes integrados killson lo suficientemente amables como para enviarlos SIGCONTa procesos suspendidos para que no tenga que hacerlo usted mismo, pero eso no ayudará si el proceso bloquea la señal que está enviando o si el manejo de la señal hace que los procesos se suspendan. nuevamente (si un proceso en segundo plano intenta leer desde el terminal, por defecto, se enviará SIGTTIN, lo que suspende el proceso si no se maneja).

PSkocik
fuente
1
¿Por qué demonios usarías SIGABRT? Está destinado a indicar un error del programa. SIGKILL está aquí, ya que quiere matar el programa ahora, lo quiera o no.
Gilles 'SO- deja de ser malvado'
1
En realidad, parece SIGTERMque ahora despierta los procesos de sueño, al menos si no tienen controladores para ello. Creo que no solía funcionar de esta manera, ya que recuerdo haber tenido que hacerlo bgo fgalgo antes de que recibiera la señal y se fuera. Pero probé con awk 'BEGIN{while(42){}}' &, y strace kill $!, y solo hay una kill(2)llamada al sistema, con SIGTERM.
Peter Cordes
6

vimestá instalando manejadores de señal (y probablemente también configurando sigprocmask(2)) para ignorar las señales comunes para que los archivos que se están editando no se pierdan debido a un control parásito + c o una señal de eliminación aleatoria. Un programa más simple se elimina fácilmente:

% 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

Hacer la vimsalida (de manera segura) requeriría un controlador de señal vimque acepte TERMo USR1algo, guarde (o descarte) cualquier memoria intermedia, etc. ¿Qué está tratando de hacer para que la vimsalida sea así?

thrig
fuente
"¿Qué intentas hacer para que vim salga así?" - nada, era un archivo genuino "tmp" que estaba editando. vimfue solo una elección mal concebida del programa para probar la suspensión.
OJFord
1
"ignorar las señales comunes para que los archivos que se están editando no se pierdan debido a un control parásito + c o una señal de eliminación aleatoria", pero tan pronto como fglo dejé, ¿solo se detuvo mientras estuvo suspendido?
OJFord
2
@OllieFord: solo SIGKILLdespierta un proceso de sueño para que pueda morir. Enviar señales a un proceso suspendido que tiene controladores personalizados para ellos no lo despierta. (Aparte de SIGCONT, la señal de continuación, por supuesto. bgY fgenviar SIGCONT.)
Peter Cordes