16

I was slightly confused by:

% 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

So I resigned to just "do it myself" and wonder why later:

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

Oh!

Makes sense really, now that I think about it, that vim has to be running in order for it's signal handler to be told to quit, and to do so.

But obviously not what I intended.

Is there a way to "wake and quit" in a single command? i.e., a built-in alias for kill %N && fg %N?

Why does resuming in the background not work? If I bg instead of fg, Vim stays alive until I fg, which sort of breaks my above intuition.

17

vi-vi-vi is of the devil. You must kill it with fire. Or SIGKILL:

kill -KILL %1

The builtin kills are kind enough to send SIGCONT to suspended processes so that you don't have to do it yourself, but that won't help if the process blocks the signal you're sending or if handling the signal causes the processes to become suspended again (if a background process tries to read from the terminal, by default, it'll be sent SIGTTIN, which suspends the process if unhandled).

  • 1
    Why on earth would you use SIGABRT? It's meant to indicate a program bug. SIGKILL is right here since you want to kill the program now whether it wants it or not. – Gilles Aug 15 '15 at 22:33
  • 1
    Actually, it looks like SIGTERM wakes sleeping processes now, at least if they don't have handlers for it. I think it didn't used to work this way, since I remember having to bg or fg something before it would receive the signal and go away. But I tested with awk 'BEGIN{while(42){}}' &, and strace kill $!, and there's only one kill(2) system call, with SIGTERM. – Peter Cordes Aug 16 '15 at 16:12
6

vim is installing signal handlers (and probably also setting sigprocmask(2)) to ignore common signals so that any files being edited are not lost due to a stray control+c or random kill signal. A simpler program is readily killed:

% 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

Making vim exit (safely) would require a signal handler in vim that accepts TERM or USR1 or something, saves (or discards?) any buffers, etc. What are you trying to do to need to make vim exit like this?

  • "What are you trying to do to need to make vim exit like this?" -- nothing, it was a genuinely "tmp" file that I was editing. vim was just an ill-conceived choice of program to test out suspension. – OJFord Aug 15 '15 at 20:40
  • 1
    "ignore common signals so that any files being edited are not lost due to a stray control+c or random kill signal" -- but as soon as I fg'd ti did quit, it only stopped for as long as it was suspended? – OJFord Aug 15 '15 at 20:42
  • 2
    @OllieFord: Only SIGKILL wakes a sleeping process so it can die. Sending signals to a suspended process that has custom handlers for them does not wake it. (Other than SIGCONT, the continue signal, of course. bg and fg send SIGCONT.) – Peter Cordes Aug 16 '15 at 16:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.