emacsclient für den Zugriff auf den Remote-Emacs-Server

8

Ich versuche, eine Emacsclient-Sitzung von einem Remote-Host aus zu öffnen. Ich habe die folgenden Schritte auf der Tramp-Website ausgeführt. Wie kann ich mit TRAMP eine Verbindung zu einer Remote-Emacs-Sitzung herstellen?

Ich werde dich durch die Stufe führen

  1. auf dem Remote-Host in .emacs-Datei

    (require 'server)
    (setq server-host "<IP ADDRESS of remoteHost>"
          server-use-tcp t)
    (server-start)
    
  2. Starten Sie die Emacs-Sitzung auf dem Remote-Host

  3. Kopieren Sie die Datei ~ / emacs.d / server / server von remoteHost nach localHost. Behalten Sie den gleichen Pfad bei. (localHost: ~ / emacs.d / server / server)

  4. auf lokaler Host-Emacs-Shell

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

Habe aber den folgenden Fehler auf meinem localHost bekommen

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

Es scheint also eine Verbindung zu remoteHost herzustellen, kann jedoch keine Route finden. Ähnliche Fragen wurden zu SO gestellt. Hier und hier . Es gibt auch einen netten Code zum direkten Kopieren von ~ / .emacs.d / server / server von remoteHost nach localHost hier .

Jede Hilfe wird sehr geschätzt.

Update Ich habe weitere Informationen zu diesem Thema gesammelt. Es scheint, dass eine Reihe von Menschen diese Aufgabe versucht haben und einige scheinen erfolgreich gewesen zu sein, aber ich konnte eine Lösung für mein spezifisches Problem finden. Verwenden von Emacs Server und Emacsclient auf anderen Computern als andere Benutzer

Ähnliche Fragen wurden auch zu emacs.stack.exchange gestellt, wie zum Beispiel, wie ich den Emacsclient verwende, um eine Verbindung zu einer Remote-Emacs-Instanz herzustellen

Update1

Es gibt eine interessante Post hier Grafiken mit ssh weiterleiten. Es ist einfach zu implementieren und funktioniert ziemlich gut, wenn Ihre Verbindung gut genug ist, aber kein Tramp verwendet wird.

DJJ
quelle
Frage 1: Werden die Remote-Server UNIX oder Linux sein und ein SSH-Daemon ausgeführt? Frage 2: Sind die Versionen aller Remote-Emacsclients mit der lokalen Emacs-Version kompatibel? Ich habe Remote-Emacsclients erfolgreich eingerichtet und verwendet, um eine Verbindung zu meinen lokalen Emacs herzustellen, die im Daemon / Server-Modus ausgeführt werden.
Melioratus
Ja zu Ihren beiden Fragen.
DJJ

Antworten:

8

Ich denke, eines der Dinge, die in den FAQ unklar sind, ist die Notwendigkeit, dass sowohl Server als auch Client voneinander lösbar sind. Sie können diesen Thread aus dem Jahr 2009 sehen. Irgendwann habe ich ihn damals zum Laufen gebracht, aber jetzt sehe ich dasselbe wie das OP. Folgendes habe ich versucht:

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

Ich habe den Server folgendermaßen gestartet:

$ emacs -Q -l setup.el

Dies gibt Ihnen jedoch ein Emacs-Fenster. Wenn Sie das nicht möchten, kommentieren Sie die (server-start)Zeile aus und starten Sie Emacs wie folgt:

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

Jetzt habe ich auf dem Remote-Computer das Cookie wie in den FAQ angegeben kopiert und versucht, den Client wie folgt zu starten:

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

192.168.2.200 ist die IP des Remote-Clients. Aus diesem Grund ist eine bidirektionale Namensauflösung erforderlich. Dies /ssh:[email protected]:/path/to/fooist im Wesentlichen der Tramp-Pfad, den Sie dem Server zur Remote-Bearbeitung geben würden.

Ich sehe einen Fehler wie beim OP. Ich lief emacsclientunter gdb und führte das Problem auf einen Fehler beim Verbinden mit dem Socket zurück.

von 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;
    }

Ich habe es dann unter ausgeführt straceund sehe Folgendes:

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 +++

Zu diesem Zeitpunkt bin ich mir nicht sicher, was falsch läuft, da ich Ping und SSH in den Server kann.

Quarky
quelle
Sieht so aus, als ob meine Tests etwas falsch waren. Es wurden mehrere andere Server ausgeführt, was zu falschen Schlussfolgerungen führte. Ich werde die Antwort bald mit dem aktualisieren, was ich finde.
Quarky
Danke @suvayu für deine Antwort. Obwohl es nicht die genaue Antwort auf meine Frage ist, habe ich einen Nebenschritt zum Problem gepostet. Aber es scheint, dass Ihre Antwort die bisher naheliegendste Lösung ist. Ich werde die Frage für alle Fälle offen lassen
DJJ
@ DJJ Ich finde das fair. Wenn ich eine Lösung finde, aktualisiere ich die Antwort.
Quarky
3

Das ist nicht genau die Antwort auf meine Frage, aber ich habe es geschafft, das Problem zu umgehen, indem ich diese Lösung aus einem Beitrag in SO verwendet habe . Ich möchte nur die Lösung mit demjenigen teilen, der immer noch damit zu kämpfen hat.

Der Schlüssel verwendet dtach mit tramp, um den Prozess auf dem Remote-Host am Leben zu erhalten, selbst wenn Sie die Verbindung zum Server trennen.

Hier ist der Befehl zum Starten von R auf dem Server. Es ist der gleiche Code auf SO, außer dass ich die Portweiterleitung aktiviere, um auf dem Remote-Server erstellte Grafiken anzuzeigen

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

Solange Sie den Prozess nicht absichtlich beenden oder der Server nicht neu startet, können Sie die Verbindung nach Belieben trennen und den Prozess wiederherstellen, wenn Sie erneut eine Verbindung herstellen.

Es ist einfach, es auch auf andere Remote-Prozesse auszudehnen. Hier ist die, die ich zum Beispiel für Python verwende

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

Ich muss immer noch beide Funktionen zusammenführen, um präziser zu sein. Aber es könnte dich zum Laufen bringen.

DJJ
quelle