12

I use browse-url/browse-url-firefox to open links in Firefox from within Emacs 24.5.1 under Linux (Fedora 23) which in essence executes the firefox executable with the URL by start-process. If there is already a Firefox instance running, this will in turn cause the URL to be opened in a new tab and terminate the firefox executable spawned from Emacs, but otherwise a new Firefox instance will be running as a process child of Emacs (for testing purposes, this is equivalent to M-! sleep 1h & RET).

If I then want to exit Emacs, it asks me "Active processes exist; kill them and exit anyway?" with the option to either kill the Firefox instance or, well, leave Emacs running. Instead I would like to "detach" the firefox process from the Emacs parent so that I can exit Emacs while keeping the Firefox instance running.

Is it possible to spawn processes from Emacs that "survive" exiting Emacs, or must all spawned processes die when Emacs exits?

Tim Landscheidt
  • 467
  • 3
  • 8
  • Are you running Emacs on a Windows machine by any chance? It sounds similar to an issue I never got an answer to from about 2 years ago -- **How to delete a process from Emacs without killing the subprocess**: http://stackoverflow.com/q/19747637/2112489 On OSX, for example, the behavior is different -- i.e., I can open an external application with `start-process` (like a pdf viewer) and Emacs thinks its job has finished. – lawlist May 19 '16 at 02:48
  • No, I'm using Linux (Fedora 23). I'll amend the question to reflect that. – Tim Landscheidt May 19 '16 at 04:19

3 Answers3

5

here's solution, shorting @abo-abo's answer.

(cond
     ((string-equal system-type "windows-nt") ; Windows
      // ...
      )
     ((string-equal system-type "gnu/linux")
      (start-process "my-browse"
                     nil "setsid"
                     "firefox"
                     (concat "file://" buffer-file-name ))

      ;; (browse-url ξurl)
      )
     ((string-equal system-type "darwin") ; Mac
                // ...
                ))

Note that condition is necessary, because Mac doesn't have setsid.

Xah Lee
  • 1,756
  • 12
  • 11
  • See the answer [here](https://emacs.stackexchange.com/a/65040/26163) for an updated answer that should also work for Mac's – dalanicolai May 27 '21 at 15:31
5

Currently the best way to achieve this (although it does not work for Windows) is by using the command call-process with the destination argument set to 0 (see https://www.gnu.org/software/emacs/manual/html_node/elisp/Synchronous-Processes.html).

E.g. to start firefox you could use:

(call-process "firefox" nil 0 nil "www.spacemacs.org")
dalanicolai
  • 6,108
  • 7
  • 23
1

Here's a command that does what you want:

(defun ora-dired-start-process (cmd &optional file-list)
  (interactive
   (let ((files (dired-get-marked-files
                 t current-prefix-arg)))
     (list
      (unless (eq system-type 'windows-nt)
        (dired-read-shell-command "& on %s: "
                                  current-prefix-arg files))
      files)))
  (if (eq system-type 'windows-nt)
      (dolist (file file-list)
        (w32-shell-execute "open" (expand-file-name file)))
    (let (list-switch)
      (start-process
       cmd nil shell-file-name
       shell-command-switch
       (format
        "nohup 1>/dev/null 2>/dev/null %s \"%s\""
        (if (and (> (length file-list) 1)
                 (setq list-switch
                       (cadr (assoc cmd ora-dired-filelist-cmd))))
            (format "%s %s" cmd list-switch)
          cmd)
        (mapconcat #'expand-file-name file-list "\" \""))))))

(define-key dired-mode-map "r" 'ora-dired-start-process)

The key thing here is to use nohup.

See the source here.

abo-abo
  • 13,943
  • 1
  • 29
  • 43
  • Thanks! `nohup` is a nice solution. Unfortunately I find your answer too "distracting" for someone just looking for how to achieve the goal. Could you please trim the source down to something like `(shell-command "nohup sleep 1h &")` and add an explicit note that "detaching" from an existing process is not possible so that I can accept the answer? – Tim Landscheidt May 22 '16 at 04:36
  • I was told 'setsid' was better than 'nohup'. – YoungFrog May 22 '16 at 06:07