【问题标题】:How to gracefully shutdown emacs daemon? [closed]如何优雅地关闭 emacs 守护进程? [关闭]
【发布时间】:2010-11-13 03:22:56
【问题描述】:

登录 Ubuntu 时,我使用 Ubuntu 的启动程序启动了一个 Emacs(版本 23)守护程序。然后,每当我需要编辑某些东西时,我都会启动 Emacs 客户端。当我从 Ubuntu 注销时,它说 Emacs 仍在运行,当然。我需要在某处附加一个脚本来告诉 Gnome 在我注销/关闭时关闭 emacs。

1) 脚本应该是什么样的? “kill-emacs”似乎不起作用。

2) 我应该把这个脚本放在哪里?启动程序(系统->会话菜单)面板中没有任何看起来有用的东西。我更喜欢在用户帐户中工作的东西,而不是破解 PostSession 脚本或其他具有 root 访问权限的东西。

【问题讨论】:

  • [当您等待真正的答案时] 类似: emacsclient -e "(kill-emacs)" 会做到这一点。 (您可能需要 save-buffers-kill-emacs 代替;它首先要求确认。)
  • 在 .bash_logout 中加入 ShreevatsaR 所说的内容有用吗?我忘了。是否仅在退出登录 shell 时触发?
  • 这对 SU 来说是一个问题,因为它与编程无关。
  • @seth: .bash_logout 在退出登录 shell 时运行,即在 Gnome 关闭之后 @Torok: 超级用户处于私有测试阶段。在那之前,这就是我所拥有的。

标签: emacs ubuntu emacs23


【解决方案1】:

This linuxquestions.org page 有一个 Python 脚本,可以在登录期间运行,它监听 Gnome 在关机期间发出的“保存自己”事件。您可以修改它以执行以下操作:

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

官方文档:https://www.emacswiki.org/emacs/EmacsAsDaemon#toc8

【讨论】:

  • 我在 Ubuntu 11.10 下测试过,效果很好!
  • 如果您的系统没有“自救”事件,您可以通过在启动时运行 shell 脚本来伪造一个.该脚本将空闲直到捕获,然后可以运行您分配的任何功能——例如调用emacsclient -e "(save-buffers-kill-emacs)"
  • 在运行此行之前,有什么方法可以检查后台运行的 emacs 守护进程,当我运行它时,如果 emacs 不能在后台运行,它会记录长消息@genehack
【解决方案2】:

如果您使用 systemd,您可能会对这个单元文件感兴趣,它可以让您从控制台/远程系统中优雅地管理 Emacs 服务器:

[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

(它以与上面已经建议的方式相同的方式杀死守护进程。)

您可以将单元文件命名为 ~/.config/systemd/user/emacs.service 以便它绑定到您的用户而不是以 root 身份运行它;管理它:

$ systemctl --user {启用、禁用、启动、重启、停止} emacs.service

请注意:我从其他地方拿到这张纸条,但不记得在哪里。

【讨论】:

【解决方案3】:

只需打开一些终端和pkill -TERM emacs

【讨论】:

  • 请参阅 this answer 了解为什么这不是解决方案。
【解决方案4】:

willert 的回答包含一个小错误。它必须看起来像


(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)))

【讨论】:

    【解决方案5】:

    ShreevatsaR 的另一个附录:python 脚本就像一个魅力,但我建议使用

    emacsclient -e '(let ((last-nonmenu-event nil))(save-buffers-kill-emacs))'
    作为命令。将 last-nonmenu-event 设置为 nil 会强制 emacs 进入鼠标模式,因此您会在 minibuffer 中获得“不错的”对话框而不是提示。

    或者更花哨(在您的 emacs 配置中):

    (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)))
    

    然后:

    emacsclient -e '(shutdown-emacs-server)'

    【讨论】:

    • 在终端中启动是否有效?它一直告诉我:ERROR: Assertion failed: (not x-initialized)
    【解决方案6】:

    我认为在 /etc/init.d 中使用脚本是一种更简洁的解决方案。 在这里查看更多详情 http://www.emacswiki.org/emacs/EmacsAsDaemon

    【讨论】:

    • 也许,但前提是您是该机器的唯一用户。即便如此,必须以那里呈现的方式指定用户似乎有点笨拙。
    【解决方案7】:

    也许最通用的解决方案是在系统 PostSession 目录中放置一个脚本,该脚本运行 ~/.logout-d 中的每个可执行脚本,或类似的东西。然后你可以把你喜欢的任何脚本放在 ~/.logout-d 中,它们会在注销时运行。

    脚本可能像run-parts ~/.logout.d 一样简单。

    注意:未经测试,尽管我确实使用了一个启动脚本,它执行run-parts ~/.autostart.d,并且一直运行良好。

    编辑:当然,修改上面的 python 脚本以执行相同的命令同样容易,但我个人不喜欢为我的整个会话加载脚本只是为了在注销时运行命令的想法。

    【讨论】:

      【解决方案8】:

      您可以将emacsclient -e "(kill-emacs)" 放在 GDM 的 PostSession 目录中或直接放在默认脚本中:

      /etc/gdm/PostSession/Default
      

      另见GDM documentation

      【讨论】:

      • 谢谢,但我的帖子说我不想使用 PostSession,因为它需要(AFAIK)root 访问权限才能修改它。如果用户可以在自动启动中添加一些东西,那么应该有一种方法可以在“自动关闭”中添加一些东西。
      【解决方案9】:

      ShreevatsaR 是对的,答案是 kill-emacssave-buffers-kill-emacs,它们都是交互式的,因此可以在 Emacs 中使用 M-x save-buffers-kill-emacs 运行。这可能是最好的方法,因为您可以保存修改后的文件。

      另一种方法是制作这样的 shell 文件:

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

      您可以从任何您喜欢的地方运行(菜单图标、面板等)。

      【讨论】:

      • 我认为提问者想要的是可以放在 GNOME 被要求注销时自动执行的地方。 (实际上,这更像是一个 Gnome/Ubuntu/X 问题,而不是 Emacs 问题。)
      • 是否有特定的信号表明 emacs 守护进程会监听关闭?
      • sudo killall emacs 也适用于@haxney
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-01
      • 2014-11-03
      • 1970-01-01
      相关资源
      最近更新 更多