前面是我的探索过程,可以直接翻到最后看完整的正确步骤!
前言
最近在服务器上跑深度学习的代码,PyCharm配置好远程的解释器以后,部署运行debug都很完美,再也不用GitHub中转了。但是有个问题,我想用matplotlib绘图,但是发现远程的服务器并不能把图形界面传回来,这怎么办呢?其实想想,之前用ssh连接服务器,也不能用gedit之类的东西,因为terminal里面不能有GUI啊。
X11Forwarding
经过一番搜索,发现一个ssh的功能,X11 Forwarding,这个功能就是可以把图形界面给传回来,具体怎么回事如果感兴趣可以自己去搜一搜,这里就不赘述了。
环境介绍
我自己使用的是一台MacBook配PyCharm:
PyCharm 2017.2.4
Build #PY-172.4343.24, built on October 20, 2017
JRE: 1.8.0_152-release-915-b12 x86_64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Mac OS X 10.13.1
远程(局域网)服务器操作系统Linux Mint,可以理解为ubuntu:
System Info
开始配置
1. 配置远程服务器
需要在远程服务器上安装好xorg;
sudo apt install xorg
之后在/etc/ssh/sshd_config中打开X11Forwarding;
sudo vim /etc/ssh/sshd_config
把X11Forwarding设置成yes,如上图,保存退出。
重启远程服务器的ssh服务,使配置生效;
sudo /etc/init.d/ssh restart
这样服务器端就配置完了。
2.配置自己的电脑
由于macOS在新版中去掉了x11的支持,Mac 不再随附 X11,但 XQuartz 项目会提供 X11 服务器和客户端库。所以我们只要安装一下XQuartz就好了。https://support.apple.com/zh-cn/HT201341
安装好XQuartz以后,把自己电脑的X11Forwarding打开;
sudo vim /private/etc/ssh/sshd_config
把X11Forwarding设置成yes,如上图所示,保存退出。
如果你用的是windows,可以搜索一下XMing,可以提供相同的功能。
重启电脑使其生效。
测试一下
使用ssh登录远程服务器并开启X服务,只需要在ssh后面加上-X的参数就行了,在自己电脑的terminal输入:
ssh -X username@host
试试有没有成功:
gedit
我们在自己的电脑上成功显示了一个来自远程服务器的窗口!那么说明我们已经成功配置了。
PyCharm配置
接下来,我们就可以配置PyCharm了。
写一段简单的matplotlib画图的python代码:
import matplotlib.pyplot as plt
x = range(10)
y = range(10)
plt.plot(x, y)
plt.show()
我们尝试使用远程解释器运行一下,点击pycharm的运行按钮,发现报错了:
_tkinter.TclError: no display name and no $DISPLAY environment variable
提示我们没有DISPLAY这个环境变量。
经过我的一番搜索,DISPLAY的设置方法如下:
首先,在自己的电脑上打开终端,使用带X转发的ssh登陆远程服务器:
ssh -X username@host
登陆之后,输入echo $DISPLAY
查看环境变量DISPLAY的值,我这里是localhost:11.0
,每个电脑的值会不一样,不过一般是localhost:10.0
,把这个值复制下来,添加到PyCharm中;
Pycharm->Preferences->Build, Execution, Deployment->Console->Python Console,点击Environment variables后面的...,添加我们刚刚看到的DISPLAY变量,如图所示:
好了,我们再试一下运行之前的代码:
_tkinter.TclError: no display name and no $DISPLAY environment variable
卧槽,为什么还是说没有DISPLAY环境变量啊!
又是一番搜索,原来在run configuration里面还要设置一遍:
点击运行按钮左边的下拉三角形->edit configurations ;
选中我们运行的configuration,我这里是test,点右边的Environment variables的...添加一个DISPLAY变量,我这里是
localhost:11.0
。configuration
OK,我们再来运行试试:
_tkinter.TclError: couldn't connect to display "localhost:11.0"
好吧,还是报错了,无法连接显示"localhost:11.0"。虽然报错,但是错误变了,终究是一个好事,起码说明我们环境变量设置成功了。
经过一番尝试,解决办法是要开着ssh -X的终端,才能接收到服务器发来的图形界面。
完整步骤
所以正确的流程是怎么样的呢:
- 自己电脑上ssh -X登陆远程服务器:
ssh -X username@host
- 查看远程服务器DISPLAY环境变量的值:
echo $DISPLAY
echo $DISPLAY -
保持开着ssh -X的终端运行,修改PyCharm的run configuration,增加环境变量与第二步中的DISPLAY值一致:
PyCharm configuration - 保持开着ssh -X的终端运行,运行我们的Python代码。
好了,看看我们千辛万苦画出来的图吧!
Figure 1
这张图是在远程服务器上画出来,然后通过X协议将图形界面转发回来的结果,还是很棒的。
总结
PyCharm无疑是开发神器,远程解释器和部署都非常方便。但是它没有内建X11转发的支持,导致了最后那个大坑,在需要使用matplotlib等画图的时候,配置了DISPLAY环境变量但是没法连接显示,需要借助终端,一直开着ssh -X的连接才能完成界面显示。顺便吐槽一下,其实在run configuration里面设置了DISPLAY环境变量就OK了,在Python Console里面设置的应该是别的地方用的环境变量,并不是我们运行Python脚本的环境变量。
网友评论