55 Stimmen

Die Verwendung des Emacs-Servers und von emacsclient auf anderen Maschinen als anderen Benutzern

Ich weiß, dass ich nach dem Aufruf von (start-server) innerhalb einer bestehenden Emacs-Sitzung dann emacsclient -c (auf demselben Computer) verwenden kann, um neue Frames zu erstellen, die sich mit diesem Server verbinden, sodass jeder neue Frame, der von emacsclient erstellt wird, auf denselben Satz gemeinsam genutzter Daten (z. B. Puffer) zugreifen kann.

Die meisten Dokumentationen, die ich gefunden habe, konzentrieren sich auf den Anwendungsfall "Gib mir schnellen Zugriff auf mein lokales Emacs", und daher gibt es zwei Dinge, zu denen ich noch keine Details gesehen habe:

  1. Kann emacsclient -c auf von anderen Benutzern gestartete Emacs-Server zugreifen, oder ist es fest verdrahtet, nur Sitzungen zu erkennen, die von meinem eigenen Benutzer gestartet wurden?

  2. Unterstützt der Emacs-Server (direkt oder indirekt) entfernte Verbindungen? Das heißt, gibt es eine Möglichkeit, Emacs (möglicherweise unter Einbeziehung von SSH) so einzurichten, dass Aufrufe von emacsclient -c auf remote Maschinen Zugriff auf den lokalen Status meines Emacs-Servers haben?

(Falls Sie es noch nicht erraten haben, was ich letztendlich tun möchte, ist, die oben genannten Techniken zu kombinieren, um rudimentäre kollaborative Bearbeitungsunterstützung zu bieten.)


Das ist ein Realitätsproblem, also das, woran ich arbeite:

  • Die erforderliche Funktionalität sollte bereits in Emacs implementiert sein (23.3.1, 64-Bit). Ich kann zu Emacs-Erweiterungen aus den standardmäßigen Ubuntu-Repositories greifen, aber das würde ich lieber vermeiden. (Das schließt meiner Meinung nach Rudel aus, leider.)
  • Keine neuen Benutzer oder Benutzerfälschungen. Lösungen sollten mit dem vorhandenen Benutzerkonten-Set arbeiten und Benutzer dürfen nicht vorgeben, andere Benutzer zu sein (z. B. über su oder ssh).

Falls es eine Rolle spielt, befinden sich die Maschinen in einem privaten LAN, haben OpenSSH-Clients und -Server installiert (und laufen), und alle Benutzer können eine Verbindung zu (ihrem eigenen Konto auf) allen Maschinen herstellen, haben jedoch kein gemeinsames Dateisystem.


Weiß also jemand, ob der Emacs-Server

  • den Zugriff auf andere Benutzer gewähren kann, oder
  • remoteen Zugriff bieten kann?

BEARBEITEN

Wie in rwb's Antwort kommentiert, ist klar, dass die lokal geöffneten neuen Fenster durch Ausführen von emacsclient -c tatsächlich vom remoteen Emacs-Serverprozess erstellt werden. Das heißt, emacsclient löst einfach das entsprechende Verhalten im Server aus. Dies führt zu einigen Problemen mit falschen Anzeigeeinstellungen, da der Server normalerweise keinen Zugriff auf den lokalen Desktop hat (siehe unten). Ich kann jedoch jetzt eine Verbindung zu einer remoteen Emacs-Sitzung herstellen, wenn ich die folgende Befehlssequenz verwende:

In einem Terminal, wobei 1.22.333.44 die IP-Adresse von remotehost ist:

ssh -t -X remotehost \
  "emacs -nw --eval
   '(progn (setq server-host \"1.22.333.44\" server-use-tcp t) (server-start))'"

Dann in einem anderen (auf demselben Computer):

scp remotehost:.emacs.d/server/server /tmp/server-file
DISPLAY=localhost:10 emacsclient -c -f /tmp/server-file

Der emacsclient-Befehl veranlasst den remoteen Emacs-Server (den er in /tmp/server-file findet), ein grafisches Emacs-Fenster (auf der lokalen Anzeige) zu öffnen, das den Status mit der auf dem entfernten Host laufenden Emacs-Sitzung teilt.

Da der entfernte Emacs-Server über ssh -X gestartet wurde, bietet SSH ihm Zugriff auf meine lokale Anzeige über eine "gefälschte" :10-Anzeige. Das an ihn übergebene DISPLAY=:10 (über emacsclient) führt daher dazu, dass ein Fenster auf meinem lokalen Desktop geöffnet wird.


Obwohl der oben beschriebene Ansatz das Kästchen "Emacs-Server auf dem remoteen Rechner ausführen und lokal mit emacsclient darauf zugreifen" ankreuzt, ist er sehr begrenzt. Tatsächlich ist es nicht viel anders als das Ausführen des Servers und der Clients alle lokal als einzelnen Benutzer: Der einzige Unterschied besteht darin, dass der Server jetzt remote ist und daher Zugriff auf unterschiedliche Systemressourcen hat.

Leider ist das Starten über ssh -X der einzige Weg, mit dem es mir erfolgreich gelungen ist, ein Fenster auf dem X-Server eines anderen Computers zu öffnen:

  • Die Angabe eines grundlegenden DISPLAY=remote:0 führt zu nichts (da Ubuntu-X-Server mit der Option -nolisten tcp gestartet werden).

  • Die Verbindung über SSH und dann die Verwendung von DISPLAY=:0 schlägt ebenfalls fehl, aber diesmal nur aufgrund fehlender geeigneter Authentifizierungsdaten. (Ich glaube, dass dies der Fall ist: die Fehlermeldung sagt kryptisch No protocol specified / Can't open display.)

Ich denke, dass das Finden eines Weges um das zweite Problem mich wahrscheinlich deutlich näher an eine Lösung bringen würde.


Nachdem ich die Beiträge unter http://comments.gmane.org/gmane.emacs.devel/103350 (beginnend beim Beitrag '25 Oct 14:50', etwa in der Mitte) gelesen habe, frage ich mich langsam, ob dies eine der seltenen Dinge ist, die Emacs nicht kann (d. h. unmöglich sind ;-)).

Wenn jedoch jemand einen Weg kennt, wie auf entfernte X-Anzeigen ohne den oben genannten Berechtigungsfehler zugegriffen werden kann, bin ich immer noch offen für Überredung....

Zusammenfassung

Wie in rwb's Antwort angemerkt, haben meine oben genannten Fragen, ob Emacs remoteen Zugriff gewähren kann, die Dinge falsch angegangen. Es gibt kein eigentliches Problem damit, dass Emacs anderen Benutzern Zugriff gewährt (server-use-tcp und eine geeignete server-file kümmern sich darum): vielmehr ist das Problem, wie ein Prozess auf einer Maschine neue X-Fenster auf den X-Anzeigen anderer Benutzer öffnen kann (speziell muss das laufende Emacs mit (start-server) Fenster für Benutzer öffnen, die es über emacsclient -c anfordern). Diese Antwort fällt außerhalb des Bereichs dieser Frage.

Alternative Lösung

Als Workaround verwenden wir Folgendes:

  • machine0: tmux -S /tmp/shared-tmux-socket new-session
  • machine1..machineN: ssh -t machine0 tmux -S /tmp/shared-tmux-socket attach

mit geeigneten Dateiberechtigungen für /tmp/shared-tmux-socket.

Dann führen wir einen Textmodus-Emacs im gemeinsam genutzten Terminal aus. :-) Dadurch ergeben sich einige Fragen zur Benutzerfälschung, aber zumindest kann der Host alles sehen, was die Gäste tun.

16voto

rwb Punkte 538

Dies sollte einen Ausgangspunkt für das bieten, was Sie möchten.

Aus dem Info-Knoten (emacs) Optionen von emacsclient

`--server-file=SERVER-DATEI'
     Geben Sie eine "Server-Datei" an, um eine Verbindung zu einem Emacs-Server über TCP herzustellen.

     Ein Emacs-Server verwendet normalerweise ein Betriebssystemfeature namens "lokaler Socket", um auf Verbindungen zu lauschen. Einige Betriebssysteme, wie zum Beispiel Microsoft Windows, unterstützen keine lokalen Sockets; in diesem Fall verwendet Emacs stattdessen TCP. Wenn Sie den Emacs-Server starten, erstellt Emacs eine Server-Datei, die einige TCP-Informationen enthält, die von `emacsclient' benötigt werden, um die Verbindung herzustellen. Standardmäßig befindet sich die Server-Datei in `~/.emacs.d/server/'. Auf Microsoft Windows sucht `emacsclient' im Standardfall im `.emacs.d/server/'-Unterverzeichnis des Verzeichnisses, auf das die Umgebungsvariable `APPDATA' verweist.

Sie können `emacsclient' anweisen, eine bestimmte Serverdatei mit der Option `-f' oder `--server-file' oder durch Festlegen der Umgebungsvariable `EMACS_SERVER_FILE' zu verwenden.

Auch wenn lokale Sockets verfügbar sind, können Sie Emacs anweisen, TCP zu verwenden, indem Sie die Variable `server-use-tcp' auf `t' setzen. Ein Vorteil von TCP besteht darin, dass der Server Verbindungen von entfernten Rechnern akzeptieren kann. Damit dies funktioniert, müssen Sie (i) die Variable `server-host' auf den Hostnamen oder die IP-Adresse des Rechners setzen, auf dem der Emacs-Server läuft, und (ii) `emacsclient' mit der Serverdatei versorgen. (Ein praktischer Weg, dies zu tun, besteht darin, die Server-Datei auf einem vernetzten Dateisystem wie NFS zu platzieren.)

Sie sollten sich auch die Variablen server-auth-dir, server-auth-key und server-port ansehen

11voto

mavit Punkte 589

Ich denke, was du verlangst, ist definitionsgemäß unmöglich, weil wenn du einem entfernten Benutzer uneingeschränkten Zugriff auf dein Emacs gewährst, dies genauso viel "Benutzerspoofing" ist wie wenn du diesem entfernten Benutzer den Zugriff auf eine Shell über ssh ermöglichtest. Aus Sicherheitssicht ist dies wahrscheinlich eine schlechte Idee.

Außerdem sind die Ergebnisse, wenn zwei Benutzer gleichzeitig auf ein Emacs zugreifen, nicht so gut wie erhofft. Es wurde nicht mit gleichzeitigem Zugriff im Hinterkopf entworfen. Es ist schon einige Jahre her, seit ich es versucht habe, also könnte sich inzwischen etwas geändert haben, aber als ich es tat, war es ziemlich eigenartig, um es gelinde auszudrücken.

Trotzdem werde ich versuchen, deine Frage zu beantworten.

Es scheint, als würdest du hier rückwärts denken, denn gegensätzlich zu dem, was man erwarten würde, ist im Netzwerk der X11-Display der Server und die X11-Anwendung der Client. Dies überrascht, da üblicherweise das Display lokal für den Benutzer ist und die Anwendung auf einem entfernten Server läuft.

Du kannst einem laufenden Emacs Anweisungen geben, sich mit einem entfernten Display zu verbinden und ein neues Fenster mit M-x make-frame-on-display zu öffnen. Damit das funktioniert, muss der Besitzer dieses Displays dir Zugriff gewähren.

Wir gehen davon aus, dass host-l der Computer ist, auf dem Emacs läuft, und dass du ihn für einen Benutzer des Displays 0 auf host-r zugänglich machen möchtest. Beachte, dass du gesagt hast, dass du keine SSH-Weiterleitung verwenden möchtest, also wird bei Verwendung dieser Methode der gesamte Datenverkehr unverschlüsselt über das Netzwerk übertragen.

Zunächst soll sicherstellen, dass das Display host-r:0 TCP-Verbindungen akzeptiert. Du hast dein Betriebssystem nicht erwähnt, aber dies ist wahrscheinlich der Standard auf Unix und wahrscheinlich nicht auf Linux (aus Sicherheitsgründen). Falls zum Beispiel folgendes -nolisten tcp erwähnt, musst du diese Konfiguration ändern.

host-r$ ps -ef | grep X

Dann lass den Benutzer von host-r folgendes ausführen und dir die Ausgabe senden. Stelle sicher, dass du ihn warnst, dass dies dir ermöglichen wird, die vollständige Kontrolle über ihre aktuelle Desktop-Sitzung zu übernehmen, wenn du dich dafür entscheiden solltest.

host-r$ xauth list $DISPLAY
host-r/unix:0  MIT-MAGIC-COOKIE-1  01234567890abcdef0123456789abcd

Dies ist im Grunde das "Passwort" für das Display. Auf host-l platzierst du es dort, wo Emacs es finden kann, mit:

host-l$ xauth add host-r:0 MIT-MAGIC-COOKIE-1  01234567890abcdef0123456789abcd

Gib nun M-x make-frame-on-display host-r:0 ein und es sollte ein Emacs-Fenster auf dem entfernten Display erscheinen.

7voto

Thomas Koch Punkte 2773

Aaron Gallagher hat eine Lösung implementiert: http://blog.habnab.it/blog/2013/06/25/emacsclient-and-tramp/

Es funktioniert (AFAIU) wie folgt:

  • Der Emacs-Server wird mit TCP gestartet
  • Er öffnet eine Verbindung zu einem entfernten System mit Tramp-sh und öffnet einen Forward-Port ("Rückkanal")
  • Tramp-sh wird angewiesen, eine erweiterte Authentifizierungs-Cookie-Datei auf dem entfernten System zu kopieren
  • Auf dem entfernten System ruft er ein spezielles emacsclient.sh-Shellskript auf, das emacsclient emuliert, aber die Dateinamen mit dem entsprechenden Tramp-Präfix voranstellt, das in dem erweiterten Authentifizierungs-Cookie gefunden wird

Ich habe einen Kommentar zu seinem Blog-Beitrag hinzugefügt, in dem ich vorschlage, dass diese Idee auf emacs-devel diskutiert und verbessert wird.

4voto

sean_m Punkte 1544

Wenn Sie dies tun, um Personen die Möglichkeit zu geben, Dateien remote zu bearbeiten, sollten Sie sich den 'Tramp-Modus' ansehen

http://emacswiki.org/emacs/TrampMode

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X