8

I often find myself with an incomplete or invalid emacs config, which breaks the normal behavior of kill-emacs such that it stops at an error.

In this case, I would like to forcefully kill emacs, without resorting to hunting down the PID and issuing a kill from the shell. Can I do this in pure Emacs Lisp?

PythonNut
  • 10,363
  • 2
  • 30
  • 76
  • I'm not sure I follow. If kill-emacs doesn't work other elisp approaches may also be fouled up, as they probably end up calling kill-emacs one way or another. What error do you get? It may be easier to fix the error. – Tyler Dec 16 '14 at 20:37
  • I mean, you could create a function that calls kill -9 on the current Emacs pid for instance. You'd have to be very messed up to break that. – PythonNut Dec 16 '14 at 20:38
  • 5
    You can try setting kill-emacs-hook to nil before calling kill-emacs. You can also get Emacs's pid using emacs-pid and make it commit suicide by calling call-process with "kill -9". – Constantine Dec 16 '14 at 20:43
  • 1
    if you don"t want to hunt the PID, still, there is pkill & pgrep :\ – Nsukami _ Dec 16 '14 at 21:05
  • I've run into this problem as well when updating Yasnippet with yas-global-mode active. For every buffer that's used (even the minibuffer), yas-minor-mode is turned on and errors out. Note that this means the minibuffer can't be used, but you could still possibly use eval-last-sexp. – Sean Allred Dec 16 '14 at 21:10
  • I run multiple instances of emacs, so pkill will kill them all (which I don't want) and pgrep won't tell me which one is the one I want to kill. – PythonNut Dec 16 '14 at 21:10
  • 1
    Unrelated, but you might want to avoid running multiple sessions of emacs – Sean Allred Dec 16 '14 at 21:11
  • @Constantine that works very well, if you can make an answer (even a minimal one), I'll accept it. – PythonNut Dec 16 '14 at 21:16

3 Answers3

15

You can try setting kill-emacs-hook to nil before calling kill-emacs:

(defun really-kill-emacs ()
  "Like `kill-emacs', but ignores `kill-emacs-hook'."
  (interactive)
  (let (kill-emacs-hook)
    (kill-emacs)))

Alternatively, you can get Emacs's PID using emacs-pid and make it commit suicide by calling call-process with "kill -9":

(defun brutally-kill-emacs ()
  "Use `call-process' to send ourselves a KILL signal."
  (interactive)
  (call-process "kill" nil nil nil "-9" (number-to-string (emacs-pid))))
Constantine
  • 9,122
  • 1
  • 35
  • 50
  • 3
    Not a critique of the answer, just additional information: note that using signal nine (the -9 in kill -9) will orphan any processes that emacs has spawned, just as it would happen if emacs were a simple shell script.. – Sean Allred Dec 16 '14 at 22:29
  • Although TERM often fails to kill emacs in a broken state. So it may be the only thing. – PythonNut Dec 16 '14 at 23:22
  • When I call this way: emacsclient -e "(really-kill-emacs)" it kills it. But when I run it again, it try to kill already killed emacs, which leads to print out log of emacsclient ending with Emacs daemon should have started, trying to connect again@Constantine – alper Jul 19 '20 at 20:26
1

Sometimes, I end up with several unreachable emacs processes laying around. My emacsclient normally automatically starts an emacs and calls server-start--I guess there is some bug in my configuration somewhere which results in this happening more than once.

I kill the extra emacsen with killall emacs in a shell. So far, -9 hasn't been needed. (It works when there's only one emacs running, too, and I don't have to hunt down a pid!)

daveloyall
  • 1,300
  • 9
  • 21
  • Sometimes, when emacs hangs completely, a -9 is needed. Of course, this means that emacs won't be able to commit suicide, but I'm adding it just in case. – PythonNut Dec 22 '14 at 19:30
  • This was the only thing that worked for me after an ein:jupyter-notebook was preventing all other methods. I guess is was hanging somewhere, but I had already ended all Python processes and killed all buffers. – n1k31t4 Nov 07 '17 at 08:31
0

This will force kill emacs daemon from bash. If there is no emacs running and when we run emacsclient -e "(kill-emacs)", which starts emacs and kills it again. I just added simple if/else to prevent that.

  • Instead of kill-emacs you can use brutally-kill-emacs () that is defined in @Constantine's answer.
#!/bin/bash

num=$(ps aux | grep -E "[e]macs --daemon" | wc -l) if [ $num -ge 1 ]; then emacsclient -e "(brutally-kill-emacs)" > /dev/null 2>&1

# following commands guarantees 
kill -9 $(ps aux | grep -E "emacs"      | awk '{print $2}')
(killall emacs) > /dev/null 2>&1
(killall emacsclient) > /dev/null 2>&1
kill -9 $(ps aux | grep -E "[e]macs" | awk '{print $2}') > /dev/null 2>&1

else echo "emacs is already killed." fi


If you are a m

Sometimes following zombie process remain opened and consumes all the memory so kill -9 $(ps aux | grep -E "emacs" | awk '{print $2}') will be your friend.

alper 4785 100.0 0.0 4461068 7860 ?? R 1:27AM 41:42.43 /usr/local/Cellar/emacs-head@26/26.3_1/Emacs.app/Contents/MacOS/Emacs -Q -l /Users/alper/.emacs.d/elpa/async-20200809.501/async.elc -batch -f async-batch-invoke

alper
  • 1,370
  • 1
  • 13
  • 35