emacsclient para acceder al servidor remoto de emacs

8

Estoy tratando de abrir una sesión de emacsclient desde un host remoto. Seguí los siguientes pasos en el sitio web de vagabundo ¿Cómo puedo usar TRAMP para conectarme a una sesión remota de Emacs?

Te guiaré por el paso

  1. en el host remoto puesto en el archivo .emacs

    (require 'server)
    (setq server-host "<IP ADDRESS of remoteHost>"
          server-use-tcp t)
    (server-start)
    
  2. iniciar sesión de emacs en host remoto

  3. copie el ~ / emacs.d / server / server de remoteHost a localHost mantenga la misma ruta. (localHost: ~ / emacs.d / server / server)

  4. en el host local emacs shell

    emacsclient /ssh:test@remoteHost:/tmp/test.py

Pero obtuve el siguiente error en mi localHost

;; emacsclient: can't find socket; have you started the server?
;; To start the server in Emacs, type "M-x server-start".
;; emacsclient: connected to remote socket at `Remotehost`
;; emacsclient: connect: No route to host
;; emacsclient: No socket or alternate editor.  Please use:

    ;; --socket-name
    ;; --server-file      (or environment variable EMACS_SERVER_FILE)
    ;; --alternate-editor (or environment variable ALTERNATE_EDITOR)

Por lo tanto, parece conectarse a host remoto pero no puede encontrar una ruta. Se han hecho preguntas similares sobre SO. Aquí y aquí . También hay un buen código para copiar directamente el ~ / .emacs.d / server / server desde remoteHost a localHost aquí .

Cualquier ayuda será apreciada.

Actualización He reunido más información sobre el asunto. Parece que varias personas han intentado esta tarea y algunas parecen haber tenido éxito, pero pude encontrar alguna solución a mi problema específico. Usando el servidor Emacs y emacsclient en otras máquinas como otros usuarios

También se han hecho preguntas similares en emacs.stack.exchange como how-do-i-use-emacsclient-to-connect-to-a-remote-emacs-instance

Actualización1

Hay un interesante post aquí reenvío de gráficos con ssh. Es fácil de implementar y funciona bastante bien si su conexión es lo suficientemente buena, pero no utiliza vagabundo.

DJJ
fuente
Pregunta 1: ¿Los servidores remotos serán UNIX o Linux y tendrán un demonio SSH ejecutándose? Pregunta 2: ¿Las versiones de todos los clientes remotos de emacs son compatibles con la versión local de emacs? He configurado y utilizado con éxito emacsclients remotos para volver a conectarme a mis emacs locales que se ejecutan en modo demonio / servidor.
Melioratus
Sí a las dos preguntas.
DJJ

Respuestas:

8

Creo que una de las cosas que no están claras en las preguntas frecuentes es la necesidad de que tanto el servidor como el cliente puedan resolverse entre sí. Puedes ver este hilo de 2009. Finalmente, en aquel entonces lo puse a funcionar, pero ahora veo lo mismo que el OP. Esto es lo que probé:

setup.el:

(require 'server)

(setq server-name "sx-test"       ; name of the server
      server-host "192.168.2.198" ; server ip
      server-use-tcp t)

(server-start)                    ; comment out when using --daemon

Comencé el servidor así:

$ emacs -Q -l setup.el

Sin embargo, esto le dará una ventana de Emacs. Si no quiere eso, comente la (server-start)línea e inicie Emacs así:

$ emacs -Q -l setup.el --daemon

Ahora en la máquina remota, copié la cookie como se indica en las preguntas frecuentes e intenté iniciar el cliente de esta manera:

$ emacsclient -f ~/.emacs.d/server/sx-test /ssh:[email protected]:/path/to/foo

192.168.2.200 es la ip del cliente remoto. Por eso es necesaria la resolución de nombres en ambos sentidos. Esencialmente, /ssh:[email protected]:/path/to/fooes la ruta de vagabundo que le daría al servidor para editar de forma remota.

Veo una falla al igual que el OP. Me encontré emacsclientbajo gdb, y remonta el problema a un fallo en la conexión a la toma de corriente.

de emacsclient.c :

  /* Set up the socket.  */
  if (connect (s, (struct sockaddr *) &server, sizeof server) < 0) /* <-- fails here */
    {
#ifdef WINDOWSNT
      if(!(w32_window_app () && alternate_editor))
#endif
      sock_err_message ("connect");
      return INVALID_SOCKET;
    }

Luego lo ejecuté stracey veo lo siguiente:

write(1, "emacsclient: connected to remote"..., 57emacsclient: connected to remote socket at 192.168.2.198
) = 57
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(40266), sin_addr=inet_addr("192.168.2.198")}, 16) = -1 EHOSTUNREACH (No route to host)
write(2, "emacsclient: connect: No route t"..., 39emacsclient: connect: No route to host
) = 39
write(2, "emacsclient: error accessing ser"..., 80emacsclient: error accessing server file "/home/jallad/.emacs.d/server/sx-test"
) = 80
exit_group(1)                           = ?
+++ exited with 1 +++

En este punto, no estoy seguro de qué va mal, ya que puedo hacer ping y ssh en el servidor.

Quarky
fuente
Parece que mi prueba fue un poco incorrecta. Hubo varios otros servidores en ejecución que llevaron a conclusiones falsas. Actualizaré la respuesta pronto con lo que encuentre.
Quarky
Gracias @suvayu por tu respuesta. Aunque no es la respuesta exacta a mi pregunta, he publicado un paso al lado del problema. Pero parece que su respuesta es la solución más cercana hasta ahora. Dejaré la pregunta abierta por si acaso
DJJ
@DJJ Creo que es justo. Si encuentro una resolución, actualizaré la respuesta.
Quarky
3

Esa no es exactamente la respuesta a mi pregunta, pero me las arreglé para eludir el problema utilizando esta solución desde una publicación en SO . Solo queriendo compartir la solución con quien todavía está luchando con esto.

La clave es usar dtach con vagabundo para mantener vivo el proceso en el host remoto, incluso si se desconecta del servidor.

Aquí está el comando para iniciar R en el servidor. Es el mismo código en SO, excepto que habilito el reenvío de puertos para ver gráficos creados en el servidor remoto

(defvar R-remote-host "remotehost")
(defvar R-remote-session "R")

(defun R-remote (&optional remote-host session)
  "Connect to the remote-host's dtach session running R."
  (interactive (list
        (read-from-minibuffer "R remote host: " R-remote-host)
        (read-from-minibuffer "R remote session: " R-remote-session)))
  (pop-to-buffer (make-comint (concat "remote-" session)
              "ssh" nil "-X"  "-t" "-t" remote-host
              "dtach" "-A" (concat ".dtach-" session)
              "-z" "-E"  "-r" "none"
              inferior-R-program-name "--no-readline"
              inferior-R-args))
  (ess-remote (process-name (get-buffer-process (current-buffer))) "R")
  (setq comint-process-echoes t))

Mientras no elimine el proceso a propósito o el servidor no se reinicie, puede desconectarse como desee y recuperar el proceso cuando vuelva a conectarse.

También es fácil de extender a otros procesos remotos. Aquí está el que uso para python, por ejemplo

(defvar remote-host "remotehost")
(defvar remote-session "python")
(defun python-remote (&optional remote-host session)
  "Connect to the remote-host's dtach session running python."
  (interactive (list
        (read-from-minibuffer "R remote host: " remote-host)
        (read-from-minibuffer "R remote session: " remote-session)))
  (pop-to-buffer (make-comint (concat "remote-" session)
              "ssh" nil "-t" "-t" remote-host
              "dtach" "-A" (concat ".dtach-" session)
              "-z" "-E" "-r" "none"
             "python" )
         )
  (setq comint-process-echoes t))

Todavía necesito usar para juntar ambas funciones para ser más conciso. Pero podría ponerte en marcha.

DJJ
fuente