Czy można „odłączyć” proces potomny?

10

Używam browse-url/ browse-url-firefoxdo otwierania linków w Firefoksie z Emacsa 24.5.1 pod Linuksem (Fedora 23), który w zasadzie wykonuje firefoxplik wykonywalny za pomocą adresu URL start-process. Jeśli jest już uruchomiona instancja Firefox, spowoduje to otwarcie adresu URL w nowej karcie i zamknięcie firefoxpliku wykonywalnego spawnowanego z Emacsa, ale w przeciwnym razie nowa instancja Firefox będzie działała jako proces potomny Emacsa (do celów testowych , jest to równoważne M-! sleep 1h & RET).

Jeśli następnie chcę wyjść z Emacsa, pojawia się pytanie „Aktywne procesy istnieją; zabić je i wyjść mimo to?” z opcją zabicia instancji Firefoksa lub pozostawienia uruchomionego Emacsa. Zamiast tego chciałbym „odłączyć” firefoxproces od rodzica Emacsa, abym mógł wyjść z Emacsa, utrzymując działającą instancję Firefoksa.

Czy jest możliwe odrodzenie procesów od Emacsa, które „przetrwają” wychodząc z Emacsa, czy też wszystkie odrodzone procesy muszą umrzeć, gdy Emacs wyjdzie?

Tim Landscheidt
źródło
Czy uruchamiasz Emacsa na komputerze z systemem Windows przez przypadek? Brzmi podobnie do problemu, na który nie otrzymałem odpowiedzi sprzed około 2 lat - Jak usunąć proces z Emacsa bez zabicia podprocesu : na przykład stackoverflow.com/q/19747637/2112489 W OSX zachowanie jest inne - tzn. mogę otworzyć zewnętrzną aplikację za pomocą start-process(jak przeglądarka pdf) i Emacs uważa, że ​​jego zadanie zostało zakończone.
prawnik
Nie, używam Linuksa (Fedora 23). Zmienię pytanie, aby to odzwierciedlić.
Tim Landscheidt

Odpowiedzi:

3

oto rozwiązanie, zwarcie @ odpowiedź 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
                // ...
                ))

Zauważ, że warunek jest konieczny, ponieważ Mac nie ma setid.

Xah Lee
źródło
1

Oto polecenie, które robi to, co chcesz:

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

Kluczową rzeczą jest tutaj użycie nohup.

Zobacz źródło tutaj .

abo-abo
źródło
Dzięki! nohupto dobre rozwiązanie. Niestety, twoja odpowiedź jest zbyt „rozpraszająca” dla kogoś, kto szuka sposobu na osiągnięcie celu. Czy możesz skrócić źródło do czegoś w rodzaju (shell-command "nohup sleep 1h &")i dodać wyraźną notatkę, że „odłączenie” od istniejącego procesu nie jest możliwe, abym mógł zaakceptować odpowiedź?
Tim Landscheidt
Powiedziano mi, że „setid” był lepszy niż „nohup”.
YoungFrog