É possível "desanexar" um processo filho?

10

Eu uso browse-url/ browse-url-firefoxpara abrir links no Firefox a partir do Emacs 24.5.1 no Linux (Fedora 23) que, em essência, executa o firefoxexecutável com a URL por start-process. Se já houver uma instância do Firefox em execução, isso fará com que o URL seja aberto em uma nova guia e encerre o firefoxexecutável gerado pelo Emacs, mas, caso contrário, uma nova instância do Firefox será executada como um processo filho do Emacs (para fins de teste , isso é equivalente a M-! sleep 1h & RET).

Se eu quiser sair do Emacs, ele me perguntará "Existem processos ativos; mate-os e saia assim mesmo?" com a opção de matar a instância do Firefox ou deixar o Emacs em execução. Em vez disso, gostaria de "desanexar" o firefoxprocesso do pai do Emacs para que eu possa sair do Emacs enquanto mantém a instância do Firefox em execução.

É possível gerar processos do Emacs que "sobrevivem" ao sair do Emacs ou todos os processos gerados devem morrer quando o Emacs sai?

Tim Landscheidt
fonte
Você está executando o Emacs em uma máquina Windows por acaso? Parece um problema que eu nunca recebi resposta há cerca de 2 anos - Como excluir um processo do Emacs sem interromper o subprocesso : stackoverflow.com/q/19747637/2112489 No OSX, por exemplo, o comportamento é diferente - ou seja, eu posso abrir um aplicativo externo com start-process(como um visualizador de pdf) e o Emacs acha que seu trabalho terminou.
Lawlist
Não, estou usando Linux (Fedora 23). Vou alterar a pergunta para refletir isso.
Tim Landscheidt

Respostas:

3

aqui está a solução, encurtando a resposta da @ 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
                // ...
                ))

Observe que a condição é necessária, porque o Mac não possui setsid.

Xah Lee
fonte
1

Aqui está um comando que faz o que você deseja:

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

A principal coisa aqui é usar nohup.

Veja a fonte aqui .

abo-abo
fonte
Obrigado! nohupé uma boa solução. Infelizmente, acho a sua resposta muito "perturbadora" para alguém que apenas procura atingir o objetivo. Poderia, por favor, reduzir a fonte para algo como (shell-command "nohup sleep 1h &")e adicionar uma nota explícita de que "desanexar" de um processo existente não é possível para que eu possa aceitar a resposta?
Tim Landscheidt
Foi-me dito que 'setsid' era melhor que 'nohup'.
YoungFrog