Mungkinkah "melepaskan" proses anak?

10

Saya menggunakan browse-url/ browse-url-firefoxuntuk membuka tautan di Firefox dari dalam Emacs 24.5.1 di Linux (Fedora 23) yang intinya mengeksekusi firefoxexecutable dengan URL dengan start-process. Jika sudah ada instance Firefox yang sedang berjalan, ini pada gilirannya akan menyebabkan URL dibuka di tab baru dan menghentikan firefoxexecutable yang muncul dari Emacs, tetapi sebaliknya instance Firefox baru akan berjalan sebagai anak proses dari Emacs (untuk tujuan pengujian , ini setara dengan M-! sleep 1h & RET).

Jika saya kemudian ingin keluar dari Emacs, ia bertanya kepada saya, "Proses aktif ada; bunuh mereka dan keluar juga?" dengan opsi untuk membunuh instance Firefox atau, yah, biarkan Emacs tetap berjalan. Alih-alih, saya ingin "melepaskan" firefoxproses dari induk Emacs sehingga saya dapat keluar dari Emacs sambil menjaga instance Firefox tetap berjalan.

Apakah mungkin untuk menelurkan proses dari Emacs yang "bertahan" keluar dari Emacs, atau haruskah semua proses melahirkan mati ketika Emacs keluar?

Tim Landscheidt
sumber
Apakah Anda menjalankan Emacs pada mesin Windows? Kedengarannya mirip dengan masalah yang saya tidak pernah mendapat jawaban dari sekitar 2 tahun yang lalu - Bagaimana menghapus proses dari Emacs tanpa membunuh subproses : stackoverflow.com/q/19747637/2112489 Pada OSX, misalnya, perilaku berbeda - yaitu, saya dapat membuka aplikasi eksternal dengan start-process(seperti penampil pdf) dan Emacs berpikir pekerjaannya telah selesai.
hukum
Tidak, saya menggunakan Linux (Fedora 23). Saya akan mengubah pertanyaan untuk mencerminkan itu.
Tim Landscheidt

Jawaban:

3

inilah solusinya, korslet jawaban abo-abo.

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

Perhatikan bahwa kondisi ini diperlukan, karena Mac tidak memiliki setid.

Xah Lee
sumber
1

Inilah perintah yang melakukan apa yang Anda inginkan:

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

Kuncinya di sini adalah menggunakan nohup.

Lihat sumbernya di sini .

abo-abo
sumber
Terima kasih! nohupadalah solusi yang bagus. Sayangnya saya menemukan jawaban Anda terlalu "mengganggu" bagi seseorang yang hanya mencari cara untuk mencapai tujuan. Bisakah Anda memotong sumber menjadi sesuatu seperti (shell-command "nohup sleep 1h &")dan menambahkan catatan eksplisit bahwa "melepaskan" dari proses yang ada tidak mungkin sehingga saya dapat menerima jawabannya?
Tim Landscheidt
Saya diberi tahu 'setsid' lebih baik daripada 'nohup'.
YoungFrog