Matar um processo suspenso?

17

Fiquei um pouco confuso com:

% 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

Então, renunciei a "fazer sozinho" e me pergunto por que mais tarde:

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

Oh!

Faz sentido, realmente, agora que penso sobre isso, que vimdeve estar em execução para que o manipulador de sinais seja solicitado a sair e fazê-lo.

Mas obviamente não é o que eu pretendia.

Existe uma maneira de "acordar e sair" em um único comando? ou seja, um alias interno para kill %N && fg %N?

Por que a retomada em segundo plano não funciona? Se eu, em bgvez de fg, Vim permanece vivo até eu fg, o que meio que quebra minha intuição acima.

OJFord
fonte

Respostas:

20

vi-vi-vié do diabo. Você deve matá-lo com fogo. Ou SIGKILL:

kill -KILL %1

Os built-in killsão gentis o suficiente para enviar SIGCONTpara processos suspensos, para que você não precise fazer isso sozinho, mas isso não ajudará se o processo bloquear o sinal que você está enviando ou se manipular o sinal fizer com que os processos sejam suspensos novamente (se um processo em segundo plano tentar ler do terminal, por padrão, ele será enviado SIGTTIN, o que suspende o processo se não for tratado).

PSkocik
fonte
11
Por que diabos você usaria o SIGABRT? É para indicar um bug do programa. O SIGKILL está aqui, já que você deseja matar o programa agora, quer ele queira ou não.
Gilles 'SO- stop be evil'
11
Na verdade, agora parece que os SIGTERMprocessos estão em suspensão, pelo menos se eles não tiverem manipuladores para isso. Eu acho que não costumava trabalhar desta forma, desde que me lembro ter que bgou fgalgo antes que iria receber o sinal e ir embora. Mas eu testei com awk 'BEGIN{while(42){}}' &, e strace kill $!, e há apenas uma kill(2)chamada de sistema, com SIGTERM.
Peter Cordes
6

vimestá instalando manipuladores de sinal (e provavelmente também configurando sigprocmask(2)) para ignorar sinais comuns, para que os arquivos editados não sejam perdidos devido a um controle perdido + c ou um sinal aleatório de interrupção. Um programa mais simples é facilmente eliminado:

% 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

Fazer a vimsaída (com segurança) exigiria um manipulador de sinal vimque aceite TERMou USR1algo assim, salve (ou descarte?) Quaisquer buffers, etc. O que você está tentando fazer para fazer a vimsaída dessa maneira?

agitar
fonte
"O que você está tentando fazer para que o vim saia assim?" - nada, era um arquivo genuinamente "tmp" que eu estava editando. vimfoi apenas uma escolha mal concebida do programa para testar a suspensão.
OJFord 15/08/2015
11
"ignore sinais comuns para que nenhum arquivo que esteja sendo editado não seja perdido devido a um controle perdido + c ou a um sinal aleatório de interrupção" - mas assim que eu fgsaí, ele parou apenas enquanto foi suspenso?
OJFord 15/08/2015
2
@OllieFord: SIGKILLAcorda apenas um processo de suspensão para que ele possa morrer. O envio de sinais para um processo suspenso que possui manipuladores personalizados para eles não o ativa. (Outros que SIGCONT, o sinal de continuar, é claro. bgE fgenviar SIGCONT.)
Peter Cordes