56

On login to Ubuntu, I start an Emacs (version 23) daemon using Ubuntu's Startup programs. I then start Emacs clients whenever I need to edit something. When I logoff from Ubuntu, it says Emacs is still running, of course. I need to attach a script somewhere to tell Gnome to shutdown emacs when I logoff/shutdown.

1) What should the script look like? "kill-emacs" doesn't seem to work.

2) Where should I put this script? There's nothing in the startup programs (System->Sessions menu) panel that looks useful. I'd prefer something that works in the user's account, rather than hacking the PostSession script or something else with root access.

genehack
  • 136,130
  • 1
  • 24
  • 24
projectshave
  • 3,771
  • 5
  • 23
  • 24
  • 3
    [While you wait for a real answer] Something like: emacsclient -e "(kill-emacs)" will do it. (You might want save-buffers-kill-emacs instead; that asks for confirmation first.) – ShreevatsaR Jul 22 '09 at 19:18
  • Does putting something that ShreevatsaR say in .bash_logout work? I forget. Does that only fire when a login shell is exited? – seth Jul 22 '09 at 21:35
  • 1
    It's rather a question for SU as it has nothing to do with programming. – viam0Zah Jul 23 '09 at 11:55
  • @seth: .bash_logout runs when the login shell is exited,, which is after Gnome shuts down @Torok: superuser is in private beta. until then, this is all I've got. – projectshave Jul 24 '09 at 14:42

9 Answers9

42

ShreevatsaR is right, the answer is kill-emacs or save-buffers-kill-emacs, both of which are interactive, and so can be run from within Emacs with M-x save-buffers-kill-emacs. This is probably the best way to do it, since you will get to save modified files.

Another alternative is to make a shell file like this:

#!/bin/bash
emacsclient -e "(kill-emacs)"

Which you can run from wherever you like (menu icon, panel, etc).

haxney
  • 3,358
  • 4
  • 30
  • 31
  • 2
    I think what the questioner wants is something that can be put in a place that is automatically executed when GNOME is asked to log out. (So it's more of a Gnome/Ubuntu/X question than an Emacs question, actually.) – ShreevatsaR Jul 23 '09 at 03:55
  • Is there a specific signal that the emacs daemon will listen to shutdown? – CMCDragonkai Feb 21 '17 at 08:56
  • 2
    `sudo killall emacs` also works @haxney – alper Feb 08 '18 at 14:03
21

This linuxquestions.org page has a Python script that can be run during login that listens for the 'save yourself' event that Gnome emits during shutdown. You could modify that to do the:

emacsclient -e '(save-buffers-kill-emacs)'

Official docs: https://www.emacswiki.org/emacs/EmacsAsDaemon#toc8

Sergio
  • 3,317
  • 5
  • 32
  • 51
genehack
  • 136,130
  • 1
  • 24
  • 24
  • I tested it under Ubuntu 11.10 and it works great! – tatsuhirosatou Feb 13 '12 at 00:58
  • If your system doesn't have a "save yourself" event, you can fake one by running a shell script on startup that traps on `EXIT` and reads from a fifo that you create for the purpose. The script will idle until trapping and then can run any function you assign -- such as one that calls `emacsclient -e "(save-buffers-kill-emacs)"` – BallpointBen May 11 '18 at 21:41
  • Is there any way to check emacs daemon running on the background before running this line, where when I run it if emacs does not work on the background it logs long messages @genehack – alper Jun 05 '20 at 23:56
10

Another addendum to ShreevatsaR: the python script works like a charm, but I'd suggest using

emacsclient -e '(let ((last-nonmenu-event nil))(save-buffers-kill-emacs))'
as command. Setting last-nonmenu-event to nil forces emacs into mouse-mode, so you get "nice" dialog boxes instead of prompts in the minibuffer.

Or even more fancy (somewhere in your emacs config):

(defun shutdown-emacs-server () (interactive)
  (when (not (eq window-system 'x))
    (message "Initializing x windows system.")
    (x-initialize-window-system)
    (when (not x-display-name) (setq x-display-name (getenv "DISPLAY")))
    (select-frame (make-frame-on-display display '((window-system . x))))
  )
  (let ((last-nonmenu-event nil)(window-system "x"))(save-buffers-kill-emacs)))

and then:

emacsclient -e '(shutdown-emacs-server)'
willert
  • 962
  • 9
  • 12
7

If you use systemd you may be interested in this unit file that lets you manage an Emacs server gracefully from within your console/remote system:

[Unit]
Description=Emacs: the extensible, self-documenting text editor

[Service]
Type=forking
ExecStart=/usr/bin/emacs --daemon
ExecStop=/usr/bin/emacsclient --eval "(kill-emacs)"
Restart=always

# Remove the limit in startup timeout, since emacs
# cloning and building all packages can take time
TimeoutStartSec=0

[Install]
WantedBy=default.target

(it kills the daemon in the same way folks already suggested above.)

You could put and name the unit file like ~/.config/systemd/user/emacs.service so it's bind to your user instead running it as root; to manage it:

$ systemctl --user {enable,disable,start,restart,stop} emacs.service

Please note: I took this note from somewhere else, can't remember where though.

solr
  • 1,092
  • 1
  • 10
  • 14
4

I think that using a script in /etc/init.d is a cleaner solution. Check here for more details http://www.emacswiki.org/emacs/EmacsAsDaemon

sub
  • 144
  • 2
  • 4
  • 1
    Perhaps, but only if you're the only user of that machine. Even then it seems a little kludgey to have to specify a user the way presented there. – Ibrahim Jan 24 '13 at 23:43
3

the answer from willert contains a small bug. it must look like


(defun shutdown-emacs-server () (interactive)
  (when (not (eq window-system 'x))
    (message "Initializing x windows system.")
    (x-initialize-window-system)
    (when (not x-display-name) (setq x-display-name (getenv "DISPLAY")))
    (select-frame (make-frame-on-display x-display-name '((window-system . x))))
  )
  (let ((last-nonmenu-event nil)(window-system "x"))(save-buffers-kill-emacs)))
Soenke
  • 31
  • 1
1

you can put emacsclient -e "(kill-emacs)" in GDM's PostSession directory or directly in the Default script:

/etc/gdm/PostSession/Default

see also GDM documentation.

danielpoe
  • 3,756
  • 23
  • 18
  • Thanks, but my post says I didn't want to use PostSession because it requires (AFAIK) root access to modify it. If a user can add something in autostart, there should be a way to add something to "autoshutdown". – projectshave Jul 24 '09 at 14:50
1

Perhaps the most general solution would be to put a script in the system PostSession directory that runs every executable script in ~/.logout-d, or something similar. Then you can put whatever scripts you like in ~/.logout-d, and they will be run on logout.

The script might be as simple as run-parts ~/.logout.d.

Note: Untested, though I do use a startup script that does run-parts ~/.autostart.d, and that's been working fine forever.

Edit: Of course, it would be just as easy to modify the above python script to execute that same command, but I personally don't like the idea of loading a script for my entire session just to run commands on logout.

Ryan C. Thompson
  • 40,856
  • 28
  • 97
  • 159
-2

Just open some terminal and pkill -TERM emacs

GDP
  • 8,109
  • 6
  • 45
  • 82
  • 1
    See [this answer](http://stackoverflow.com/a/3738178/148680) for why that's not a solution. – chb Jul 29 '12 at 10:06