暗无天日

=============>DarkSun的个人博客

TIL: 给 dired 异步命令加 nohup,让外部程序活过 Emacs 退出

看到 一篇短文 提到一个小问题:在 dired 中按 Wdired-do-async-shell-command )用 mpv 播放视频,关掉 Emacs 后视频也停了。

dired-do-async-shell-command 虽然名字叫"async",但其实进程并没有真正独立于 Emacs。因为进程树是 Emacs → shell → mpv,Emacs 退出时杀掉子进程,shell 死了,mpv 在被 init 接管之前收到了 SIGHUP 信号,于是也跟着死了。关于 SIGHUP 为什么会杀掉后台进程,之前的 nohup、setsid 与 disown 的不同之处 里有详细解释。

解法是用 advice-adddired-do-async-shell-command 包一层,在命令前面自动加 nohup

(defun my/dired-async-shell-command-nohup (orig-fun command &optional arg file-list)
  "在 COMMAND 前加 nohup,让子进程活过 Emacs 退出。"
  (funcall orig-fun (concat "nohup " command) arg file-list))

(with-eval-after-load 'dired
  (advice-add 'dired-do-async-shell-command
              :around #'my/dired-async-shell-command-nohup))

加了之后,从 dired 启动的 mpv、firefox、gimp 等程序都不会再因为关 Emacs 而被杀。

Emacs : dired : nohup : TIL