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

Posted

技术标签:

【中文标题】如何在不退出远程服务器上的 R 的情况下恢复 X11 连接【英文标题】:How to recover X11 connection without exiting R on remote server 【发布时间】:2021-05-05 11:52:27 【问题描述】:

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

加长版

    设置

我使用 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)。它通常在一开始就可以正常工作。

    问题

但在某些时候,我可能会失去与服务器的连接一秒钟(互联网故障,*** 停止......),当我恢复与服务器的连接时,一切似乎都正常(主要@987654331 @ 连接保持)X11 连接除外

此时,任何plot(iris) 的输出将是:

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 ''
    解决方案(但正在寻找更好的解决方案!)

我目前找到的唯一解决方案是启动与服务器的新 ssh 连接并重新执行整个过程,直到启动 R 会话并绘制内容。有时,只关闭screen 会话有效,但我仍然需要重新加载conda 和我的R 会话。但这很耗时(而且很烦人),我猜可能会有更好的解决方案。

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

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

- 检查capabilities()

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

       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 连接后,唯一的区别是 X11 设置为 FALSE

- 检查DISPLAY

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

> echo $DISPLAY
localhost:10.0

在 R 中:

> Sys.getenv("DISPLAY")
localhost:10.0

我尝试设置Sys.setenv("DISPLAY"=":0.0"),但没有任何区别。

-X11UseLocalhost

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

-Xpra

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

[local] ssh -Y login@remote.server
[remote] screen -r xpra
[remote] xpra start :10
# exit screen
[local] xpra attach ssh:remote.server:10 
[remote] screen -r my_R_work_session
[remote] conda activate my_environment
[remote] nvim code.r

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

【问题讨论】:

【参考方案1】:

对于遇到这篇文章的任何人,我最终找到了一个超级简单的解决方案:您只需要在当前会话的同时启动一个新的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 小时,这将防止 X11 在任何工作会话期间停止。你甚至可以在这个配置文件中设置ForwardX11Trusted yes。但是,这些选项可能会导致安全漏洞,因此需要谨慎考虑。

【讨论】:

以上是关于如何在不退出远程服务器上的 R 的情况下恢复 X11 连接的主要内容,如果未能解决你的问题,请参考以下文章

如何在不删除最新提交的情况下恢复到上一个​​提交?

如何在不挂起的情况下返回并恢复我的应用程序?

如何在不使用身份验证的情况下保护 RESTful Web 服务

在不使用 SSMS 的情况下恢复 SQL Server 上的 .bak 数据库文件? [数据夹]

sql 如何在不设置链接服务器的情况下查询远程Microsoft SQL Server

如何在不保存的情况下退出 Eclipse