如何在不退出远程服务器上的 R 的情况下恢复 X11 连接

问题描述

简短版本:在远程机器上工作时,如何从 R 中重新启动丢失的 X11 连接?

长版

  1. 设置

我使用 Mac 11.1 并连接到远程 Linux 服务器以在 R 中编写代码(通过 Nvim-R)。我使用的步骤通常是:

ssh -Y login@remote.server
screen -r my_R_work_session
conda activate my_environment
nvim code.r

然后键入 \rf 命令以在 nvim 中打开 R 终端。

然后我可以在 R 中绘制任何内容(例如,使用 plot(iris))。该图会在我的 Mac 上的外部窗口(通过 X11 / XQuartz)中弹出。它通常在开始时工作正常。

  1. 问题

但在某些时候,我可能会失去与服务器的连接一秒钟(互联网故障,vpn 停止......),当我恢复与服务器的连接时,一切似乎都正常(main {{ 1}} 连接)X11 连接除外

此时,任何 ssh 的输出将是:

plot(iris)
  1. 解决方案(但要寻找更好的方法!)

我目前找到的唯一解决方案是启动到服务器的新 ssh 连接,然后重新执行整个过程,直到启动 R 会话并绘制内容。有时,仅关闭 Error in .External2(C_X11,d$display,d$width,d$height,d$pointsize,: unable to start device X11cairo In addition: Warning message: In function (display = "",width,height,pointsize,gamma,bg,: unable to open connection to X11 display '' 会话有效,但我仍然需要重新加载 screen 和我的 conda 会话。但这很耗时(而且很烦人),我猜可能有更好的解决方案。

  1. 我也尝试过(但没有改变任何东西)

我发现很多帖子都在用谷歌搜索这个错误,但仍然没有可以解决这个问题。

- 检查 R

在失去 X11 连接之前,capabilities() 的输出为:

capabilities()

在失去 X11 连接后,唯一的区别是 jpeg png tiff tcltk X11 aqua TRUE TRUE TRUE TRUE TRUE FALSE http/ftp sockets libxml fifo cledit iconv TRUE TRUE TRUE TRUE TRUE TRUE NLS profmem cairo ICU long.double libcurl TRUE TRUE TRUE TRUE TRUE TRUE 被设置为 X11

- 检查 FALSE

参考 this post,我检查了 DISPLAY,但似乎一切正常。 在终端中(在启动 R 之前或在 r 运行时):

DISPLAY

在 R 中:

> echo $DISPLAY
localhost:10.0

我尝试设置 > Sys.getenv("DISPLAY") localhost:10.0 但没有任何区别。

- Sys.setenv("DISPLAY"=":0.0")

This post 建议将 X11UseLocalhost 中的 X11UseLocalhost no 更改为 X11UseLocalhost yes,但这对我没有任何影响。

- /etc/ssh/sshd_config

最后,我按照 this post 的建议(可能是最有希望的)尝试使用 Xpra,但也没有任何区别。虽然在这里我不确定我是否正确使用它。这是我所做的:

Xpra

非常感谢您的任何评论和帮助!

解决方法

对于遇到这篇文章的任何人,我最终找到了一个超级简单的解决方案:您只需要在当前会话的同时启动一个新的 ssh -Y 连接。然后可以将当前会话中的 DISPLAY 参数重定向到新连接中的值。

这里有一个更详细的例子。 在当前会话中(在开始新的 ssh 连接之前),如果您在 R 终端中尝试:

> capabilites()             # returns X11 = FALSE 
> Sys.getenv('DISPLAY')     # returns localhost:xx.0
localhost:12.0
> x11('localhost:12.0')     # returns error message

现在您并行启动新的 ssh 连接:ssh -Y login@remote.server。您需要在这个新会话中找到 DISPLAY 的值,例如:

在 bash 中:

$ echo $DISPLAY
localhost:13.0

或者在 R 中:

> Sys.getenv('DISPLAY')
localhost:13.0

最后,在原R终端中,将DISPLAY参数设置为新的连接值:

> Sys.setenv('DISPLAY' = 'localhost:13.0')
> x11('localhost:13.0')  # or x11() - both should work

还有一个选择,就是修改ssh配置文件(ForwardX11Timeout)中~/.ssh/config的值。默认情况下,它通常设置为 ~20 分钟(请参阅 man ssh)。您可以尝试将其设置为一天(或更多),例如:ForwardX11Timeout 1d。如果 X11 打开少于 24 小时,这将防止它在任何工作会话期间停止。您甚至可以在此配置文件中设置 ForwardX11Trusted yes。但是,这些选项可能会导致安全漏洞,因此需要谨慎考虑。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...