Можно ли «отсоединить» дочерний процесс?

10

Я использую browse-url/ browse-url-firefoxдля открытия ссылок в Firefox из Emacs 24.5.1 под Linux (Fedora 23), который по сути выполняет firefoxисполняемый файл с URL-адресом start-process. Если уже запущен экземпляр Firefox, это, в свою очередь, приведет к открытию URL-адреса в новой вкладке и завершит работу firefoxисполняемого файла, созданного в Emacs, но в противном случае новый экземпляр Firefox будет запущен как дочерний процесс Emacs (для тестирования , это эквивалентно M-! sleep 1h & RET).

Если я затем захочу выйти из Emacs, он спросит меня: «Активные процессы существуют; убить их и выйти в любом случае?» с возможностью либо убить экземпляр Firefox, либо оставить Emacs работающим. Вместо этого я хотел бы «отсоединить» firefoxпроцесс от родителя Emacs, чтобы я мог выйти из Emacs, сохраняя работающий экземпляр Firefox.

Можно ли порождать процессы из Emacs, которые «выживают», выходя из Emacs, или все порожденные процессы должны умирать при выходе из Emacs?

Тим Ландшайдт
источник
Вы случайно запускаете Emacs на компьютере с Windows? Это звучит похоже на проблему, на которую я не получил ответа около 2 лет назад - Как удалить процесс из Emacs без уничтожения подпроцесса : stackoverflow.com/q/19747637/2112489 Например, в OSX поведение отличается То есть я могу открыть внешнее приложение с помощью start-process(например, средства просмотра PDF), и Emacs считает, что его работа завершена.
юрист
Нет, я использую Linux (Fedora 23). Я исправлю вопрос, чтобы отразить это.
Тим Ландшайдт

Ответы:

3

вот решение, короткое @ ответ 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
                // ...
                ))

Обратите внимание, что условие необходимо, потому что Mac не имеет setsid.

Ха Ли
источник
1

Вот команда, которая делает то, что вы хотите:

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

Ключевым моментом здесь является использование nohup.

Смотрите источник здесь .

Або-або
источник
Спасибо! nohupэто хорошее решение. К сожалению, я нахожу ваш ответ слишком «отвлекающим» для кого-то, кто просто ищет, как достичь цели. Не могли бы вы урезать источник до чего-то подобного (shell-command "nohup sleep 1h &")и добавить явное примечание, что «отсоединение» от существующего процесса невозможно, чтобы я мог принять ответ?
Тим Ландшайдт
Мне сказали, что "setsid" лучше, чем "nohup".
YoungFrog