55

我知道在(start-server)现有的 Emacs 会话中调用之后,我可以使用emacsclient -c(在同一台计算机上)创建连接到该服务器的新帧,以便由创建的每个新帧emacsclient都可以访问同一组共享状态(例如缓冲区)。

我发现的大多数文档都集中在“让我快速访问我的本地 Emacs”用例上,所以有两件事我还没有看到任何细节:

  1. 可以访问由其他emacsclient -c用户启动的 Emacs 服务器,还是硬连线只能检测由我自己的用户启动的会话?

  2. Emacs 服务器(直接或间接)是否支持远程连接?也就是说,是否有某种方法可以设置 Emacs(可能涉及 SSH),允许emacsclient -c远程机器的调用访问我的 Emacs 服务器的本地状态?

(如果您还没有猜到,我最终想做的是结合上述两种技术来提供基本的协作编辑支持。)


这是一个现实世界的问题,所以这就是我正在处理的问题:

  • 必要的功能应该已经内置在 Emacs 中(23.3.1,64 位)。我可以从标准的 Ubuntu 存储库扩展到 Emacs 扩展,但我不希望这样做。(可悲的是,我认为排除了Rudel。)
  • 没有新用户或用户欺骗。解决方案应该使用现有的用户帐户集,并且用户不得假装是其他用户(例如通过sussh)。

如果有什么不同的话,这些机器在私有 LAN 上,安装(并运行)OpenSSH 客户端和服务器,所有用户都可以连接到(他们自己的帐户)所有机器,但他们没有共享文件系统。


那么,有谁知道 Emacs 服务器是否可以

  • 授予其他用户访问权限,或
  • 提供远程访问?

编辑

正如 rwb 的回答中所评论的那样,很明显,通过运行在本地打开的新窗口emacsclient -c实际上是由远程Emacs 服务器进程创建的。也就是说,emacsclient只是简单地触发服务器中的相关行为。这会导致一些显示设置不正确的问题,因为服务器通常无法访问本地桌面(见下文)。但是,如果我使用以下命令序列,我现在可以连接到远程 Emacs 会话:

在一个终端中,1.22.333.44IP 地址在哪里remotehost

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

然后在另一个(在同一台机器上):

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

emacsclient命令使远程 Emacs 服务器(它可以找到 in 的详细信息/tmp/server-file)打开一个图形 Emacs 窗口(在本地显示器上),该窗口与远程主机上的 Emacs 会话共享状态。

由于远程 Emacs 服务器是通过 启动的ssh -X,因此 SSH 为它提供了通过“假”显示访问我的本地显示的权限:10。因此,DISPLAY=:10传递给它(通过emacsclient)会导致在我的本地桌面上打开一个窗口。


虽然上面的方法确实勾选了“在远程机器上运行 Emacs 服务器,使用emacsclient本地连接到它”框,但它非常有限。实际上,以单个用户的身份在本地运行服务器和客户端并没有太大区别:唯一的区别是服务器现在是远程的,因此可以访问不同的系统资源。

不幸的是,通过启动ssh -X是我能够在另一台机器的 X 服务器上成功打开窗口的唯一方法:

  • 指定一个 basicDISPLAY=remote:0无处可去(因为 Ubuntu X 服务器是使用该-nolisten tcp选项启动的)。

  • 通过 SSH 连接然后使用DISPLAY=:0也会失败,但这一次只是因为缺少合适的身份验证凭据。(无论如何,我相信是这样的:错误消息神秘地说No protocol specified/ Can't open display。)

我认为找到解决第二个问题的方法可能会让我更接近解决方案。


阅读了http://comments.gmane.org/gmane.emacs.devel/103350上的帖子(从 '25 Oct 14:50' 帖子开始,大约一半)我开始怀疑这是否可能是Emacs 不能做的罕见事情之一(即不可能 ;-) )。

但是,如果有人确实有办法在没有上述权限错误的情况下提供对远程 X 显示器的访问,我仍然愿意说服......

TL;博士

正如 rwb 的回答所指出的那样,我上面关于 Emacs 是否可以授予远程访问的问题让事情倒退了。Emacs 授予其他用户访问权限并没有真正的问题(server-use-tcp并且适当server-file地处理这一点):问题是如何允许一台机器上的进程在其他用户的 X 显示器上打开新的 X 窗口(具体来说,Emacs 正在运行(start-server)需要为通过emacsclient -c) 要求它的用户打开窗口。这个答案超出了这个问题的范围。

替代解决方案

作为一种解决方法,我们使用以下方法:

  • 机器0:tmux -S /tmp/shared-tmux-socket new-session
  • 机器1..机器N:ssh -t machine0 tmux -S /tmp/shared-tmux-socket attach

具有适当的文件权限/tmp/shared-tmux-socket

然后我们在共享终端中运行一个文本模式的 Emacs。:-) 这确实引发了一些用户欺骗问题,但至少主人可以看到客人所做的一切。

4

4 回答 4

15

这应该为您想要的东西提供一个起点。

从 info 节点(emacs) emacsclient 选项

`--server-file=SERVER-FILE'
     Specify a "server file" for connecting to an Emacs server via TCP.

     An Emacs server usually uses an operating system feature called a
     "local socket" to listen for connections.  Some operating systems,
     such as Microsoft Windows, do not support local sockets; in that
     case, Emacs uses TCP instead.  When you start the Emacs server,
     Emacs creates a server file containing some TCP information that
     `emacsclient' needs for making the connection.  By default, the
     server file is in `~/.emacs.d/server/'.  On Microsoft Windows, if
     `emacsclient' does not find the server file there, it looks in the
     `.emacs.d/server/' subdirectory of the directory pointed to by the
     `APPDATA' environment variable.  You can tell `emacsclient' to use
     a specific server file with the `-f' or `--server-file' option, or
     by setting the `EMACS_SERVER_FILE' environment variable.

     Even if local sockets are available, you can tell Emacs to use TCP
     by setting the variable `server-use-tcp' to `t'.  One advantage of
     TCP is that the server can accept connections from remote machines.
     For this to work, you must (i) set the variable `server-host' to
     the hostname or IP address of the machine on which the Emacs server
     runs, and (ii) provide `emacsclient' with the server file.  (One
     convenient way to do the latter is to put the server file on a
     networked file system such as NFS.)

您可能还想查看变量server-auth-dirserver-auth-key并且server-port

于 2012-09-23T04:31:30.860 回答
11

我认为根据定义,您所要求的内容是不可能的,因为如果您让远程用户不受限制地访问您的 Emacs,这与让远程用户通过 ssh 访问 shell 一样多的“用户欺骗”。说清楚,从安全的角度来看,这可能是一个坏主意。

此外,让两个用户访问一个 Emacs 的结果并不像您希望的那样好。它的设计并未考虑同时访问。自从我尝试它以来已经有好几年了,所以事情可能会有所进展,但是当我这样做时,至少可以说是古怪的。

不过,我会尽力回答你的问题。

听起来您正在考虑从后到前,因为与直觉相反,在网络术语中,X11 显示器是服务器,而 X11 应用程序是客户端。这是令人惊讶的,因为通常显示对用户来说是本地的,并且应用程序在某个远程服务器上运行。

您可以指示正在运行的 emacs 连接到远程显示器并使用M-x make-frame-on-display. 为此,该显示器的所有者需要授予您对其的访问权限。

我们将假设host-l是运行 Emacs 的计算机,并且您希望它可供 display 0 on 的用户访问host-r。请注意,您已经说过您不想使用 SSH 转发,因此遵循此方法将导致所有流量通过未加密的网络。

首先,确保显示器host-r:0正在接受 TCP 连接。您没有提及您的操作系统,但这可能是 Unix 上的默认设置,并且可能不在 Linux 上(出于安全原因)。例如,如果以下提及,-nolisten tcp则您需要更改此配置。

host-r$ ps -ef | grep X

接下来,让 host-r 的用户运行以下命令,并将输出发送给您。如果您选择,请务必警告他们,这将允许您完全控制他们当前的桌面会话。

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

这实际上是显示器的“密码”。在 上host-l,将它放在 Emacs 能够找到它的地方:

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

现在输入M-x make-frame-on-display host-r:0,远程显示器上应该会弹出一个 Emacs 窗口。

于 2013-05-01T20:00:46.777 回答
7

Aaron Gallagher 实现了一个解决方案: http: //blog.habnab.it/blog/2013/06/25/emacsclient-and-tramp/

它的工作原理(AFAIU)如下:

  • emacs 服务器使用 tcp 启动
  • 他使用 tramp-sh 打开与远程系统的连接,打开正向端口(“反向通道”)
  • 建议 tramp-sh 将扩展的 auth cookie 文件复制到远程系统
  • 在远程系统上,他调用了一个特殊的 emacsclient.sh shell 脚本,该脚本模拟 emacsclient,但在文件名前加上在扩展的 auth cookie 中找到的相应 tramp 前缀

I've added a comment to his blog post proposing this idea to be discussed and enhanced on emacs-devel.

于 2013-09-19T16:47:29.673 回答
4

如果您这样做是为了让人们能够远程编辑文件,您可能需要查看“tramp mode”

http://emacswiki.org/emacs/TrampMode

于 2012-09-23T04:39:25.660 回答