A Tiny Nohup: Keeping Media Alive When Emacs Exits

This post is simply about some more yak shaving and there was this one niggle that I just kept putting off, because it never really annoyed me enough, but recently I started watching a lot more video content from within dired and it finally got to me.

The problem. I press W in dired, which is bound to dired-do-async-shell-command, type mpv (or accept the default guess that my dired-guess-shell-alist-user provides for video files), and the video starts playing. Great. But when I close Emacs, the video dies too. The whole point of an async command is that it runs in the background, right?, so why does it disappear when Emacs goes away?, this is most perplexing!

20260512184707-emacs--A-Tiny-Nohup-Keeping-Media-Alive-When-Emacs-Exits.jpg

Now I should say, the answer is obvious in retrospect, but it took me a little while to actually stop and think about it properly. The command dired-do-async-shell-command adds a trailing & to the shell command and passes it to async-shell-command, which creates a shell process - Emacs is the parent of that shell, and the shell is the parent of mpv. When Emacs exits, it kills its child processes, the shell goes down, and mpv gets orphaned, which is fine actually, the problem is not being orphaned, the problem is that it receives a SIGHUP from the process group cleanup and dies before it can be reparented to init. So the media stops.

The solution is a single, tiny piece of advice. I just prepend nohup to the command string before dired-do-async-shell-command does anything with it. nohup makes the process ignore SIGHUP, so when the shell gets killed by Emacs, mpv is orphaned cleanly and keeps running.

(defun my/dired-async-shell-command-nohup (orig-fun command &optional arg file-list)
  "Wrap COMMAND with `nohup' so the process survives Emacs exit."
  (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))

That is it. Six lines of Elisp, five of which are boilerplate.

And yes, this works for any command you run through W, not just mpv. gimp, firefox, libreoffice - they all get the nohup treatment now. Which is fine, those programs usually detach themselves anyway, but it does not hurt to have it.

So that is the tweak. A tiny, one-function, one-advice change that finally stopped my videos from dying every time I closed Emacs. I suspect someone will tell me that there is a simply variable flag that I can set that enables this anyway, but hey ho!