Zabić zawieszony proces?

17

Byłem nieco zdezorientowany:

% 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

Zrezygnowałem więc z „zrobienia tego sam” i zastanawiam się, dlaczego później:

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

O!

To naprawdę ma sens, teraz, gdy o tym myślę, że vimmusi działać, aby program obsługi sygnału otrzymał polecenie odejścia i zrobienia tego.

Ale oczywiście nie to, co zamierzałem.

Czy istnieje sposób „obudzić się i wyjść” za pomocą jednego polecenia? tj. wbudowany alias dla kill %N && fg %N?

Dlaczego wznawianie w tle nie działa? Jeśli bgzamiast tego fgVim pozostanie przy życiu, dopóki ja fgnie złamie mojej powyższej intuicji.

OJFord
źródło

Odpowiedzi:

20

vi-vi-vijest od diabła. Musisz go zabić ogniem. Lub SIGKILL:

kill -KILL %1

Wbudowane killsą na tyle miłe, że wysyłają SIGCONTdo zawieszonych procesów, więc nie musisz tego robić sam, ale to nie pomoże, jeśli proces zablokuje wysyłany sygnał lub jeśli obsługa sygnału spowoduje zawieszenie procesów ponownie (jeśli proces w tle próbuje odczytać z terminala, domyślnie zostanie wysłany SIGTTIN, co spowoduje zawieszenie procesu, jeśli nie zostanie obsłużony).

PSkocik
źródło
1
Dlaczego, u licha, miałbyś używać SIGABRT? Ma oznaczać błąd programu. SIGKILL jest tutaj, ponieważ chcesz teraz zabić program, czy tego chce, czy nie.
Gilles „SO- przestań być zły”
1
W rzeczywistości wygląda na to, że SIGTERMbudzi się teraz proces uśpienia, przynajmniej jeśli nie mają do tego programów obsługi. Myślę, że nie działało to w ten sposób, ponieważ pamiętam, że musiałem bglub fgcoś takiego, zanim otrzyma sygnał i odejdzie. Ale testowałem z awk 'BEGIN{while(42){}}' &, i strace kill $!, i jest tylko jedno kill(2)wywołanie systemowe, z SIGTERM.
Peter Cordes,
6

viminstaluje moduły obsługi sygnałów (i prawdopodobnie także ustawienia sigprocmask(2)), aby ignorować typowe sygnały, aby edytowane pliki nie zostały utracone z powodu błędu sterowania + c lub losowego sygnału zabicia. Prostszy program jest łatwo zabijany:

% 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

Wykonanie vimwyjścia (bezpiecznie) wymagałoby obsługi sygnału, vimktóry akceptuje TERMlub USR1coś, zapisuje (lub odrzuca?) Dowolne bufory itp. Co próbujesz zrobić, aby zrobić vimtakie wyjście?

gałązka
źródło
„Co próbujesz zrobić, aby Vim tak zszedł?” - nic, to był plik „tmp”, który edytowałem. vimbył tylko źle przemyślanym wyborem programu do testowania zawieszenia.
OJFord,
1
„ignoruj ​​typowe sygnały, aby żadne edytowane pliki nie zostały utracone z powodu bezpańskiego sterowania + c lub losowego sygnału zabicia” - ale jak tylko fgprzestałem, to zatrzymywało się tylko tak długo, jak długo było zawieszone?
OJFord,
2
@OllieFord: SIGKILLBudzi tylko proces snu, aby mógł umrzeć. Wysyłanie sygnałów do zawieszonego procesu, który ma dla nich niestandardowe procedury obsługi, nie budzi go. (Poza SIGCONTtym, oczywiście, kontynuuj sygnał bgi fgwyślij SIGCONT.)
Peter Cordes,