XWindows太老了,歷史比Windows和Linux的開發時間都長,以至於很多人每天實際在用,但已經不知道它的存在。
XWindows目前是Linux/類Unix系統上的標准顯示配置,QT/GTK等架構也是基於XWindows的。所以通常也有很多人只關注占領桌面市場的Windows,對於敗退在邊緣的XWindows完全嗤之以鼻。
其實只從GUI層面上來對比Windows和XWindows是不公平的。XWindows設計之初就是一個顯示服務器的概念,在顯示器服務器和應用之間,有一套協議來溝通彼此,是C/S的架構,這個協議可以序列化,從而顯示的設備、跟應用運行的環境,可以不在同一台電腦之上。想想你熟悉的那些無線投影啥的,是啥時候才出現的吧。
其實我個人也很久不用XWindows了。平常工作在Mac,但是最近機器學習的任務越來越多,Mac用起來就有點不順手了。因為MacPro標准配置的opencl,遠遠比不上cuda在機器學習領域的支持廣泛。恐怕如果Mac電腦不盡快做出改變,這一波風暴足以把很多依賴於Mac環境的開發人員驅逐到Linux甚至Windows的懷抱中去了。
Windows的環境天然對NV系列顯卡和CUDA的驅動支持很充分,所以也有很多程序員使用Windows環境做開發。但很多開源系統在Windows環境的編譯甚至移植實在太艱苦了,一個應用中很大的精力都在折騰這些事情,完全不能集注到應用本身。
所以我用的方法是另外找一台電腦安裝NV顯卡,然后運行Linux,雖然CUDA和CUDNN安裝麻煩了一點點,但后續的工作就都很順暢了。
接下來就需要XWindows閃亮出廠了。當然可以另外接一套顯示和鍵盤,但那樣要占空間的...雖然顯示器、鍵盤、鼠標不貴,但空間貴啊。再有就是遠程桌面,不過那種分割的感覺,用起來會增加許多額外的麻煩。所以很多人忘記很多年的遠程XWindows,可以出來嘚瑟一下了 😃
macOS雖然也是類Unix,但從很早開始就不使用XWindows作為顯示系統了,所以現在想在Mac上使用XWindows,需要先安裝另外一個Apple發起的開源項目:XQuartz。除了去官網下載安裝包,在有Homebrew的系統上安裝更簡單:brew cask install xquartz
,安裝后是個app應用,可以在LaunchPad啟動。所有XWindows的應用,都應當先啟動xquartz應用,然后在終端中(系統自帶的終端及Xwindows中的終端都能有效轉發,其它終端不一定有效請自行確認)再啟動XWindows應用。
接着是將遠程的linux服務器上的運行結果,在本地的XQuartz中顯示。正常情況下,如果本機Mac及遠程的Linux在一個局網,或者雙方能直接ping通那就簡單了,只需要設置一個環境參數DISPLAY
。如果linux用的是bash外殼,其設置方法為:export DISPLAY=mac電腦IP地址:0.0
,冒號后面數字的意思是:第0個設備的第0個屏幕。
如果兩台電腦不在一個網段,就需要ssh大神的配合,首先查看/etc/ssh/sshd_config
中的設置,是否打開了以下兩項:
X11Forwarding yes
X11DisplayOffset 10
這兩項通常在安裝sshd的時候都是默認屏蔽的。打開之后,還要設置DISPLAY環境變量為:export DISPLAY=localhost:10.0
,其中localhost表示直接將顯示數據發送到本地,位置10跟上面sshd的設置配套,表示由本地的sshd轉發到遠端的客戶端去顯示。
最后還有一項,在mac使用ssh連接遠端的服務器的時候,首先要確保ssh命令中需要增加-X
或者-Y
參數,表示接受遠端的XWindows轉發數據。示例:ssh -Y john@123.123.123.123
。
連通之后,可以在遠端運行一下xeyes、xclock、xlogo這樣的基本應用來測試一下,看能否在本地桌面上顯示出來。題頭圖的右上角兩個應用分別是xlogo和xclock的樣子。
最后給一個在我的電腦跑起來的樣子:
看起來跟在本地運行沒有什么兩樣 😃
補充:
有些主機,或者有的時候,ssh連接過去后,執行x11應用會報錯:Error: Can't open display: localhost:10.0
,這時候仔細觀察ssh命令執行后的第一條提示,有可能會是X11 forwarding request failed on channel 0
。這表示實際本地和遠端沒有能建立起來X11協議的轉發體系,原因可能有很多,比如連接端口不是10.0,或者認證沒通過等等。
可以做以下的嘗試:
方法一:
檢查ping localhost是否能ping通,有可能是/etc/hosts
中,沒有把localhost指向127.0.0.1本機地址。這種情況可以設置顯示到127.0.0.1:10.0就可以。
方法二:
在sudo vi /etc/ssh/sshd_config
增加一行:X11UseLocalhost yes
,接着sudo service sshd restart
。然后ssh重新連過來再試試。
方法三:
- 去掉自己設置$DISPLAY環境參數的腳本,比如我通常設置在.bashrc中最后一條,把這個設置刪除,使用系統的自動設置功能。
sudo vi /etc/ssh/sshd_config
,把剛才增加的X11UseLocalhost yes
改成:X11UseLocalhost no
,接着sudo service sshd restart
sudo apt purge xauth
然后sudo apt install xauth
重新安裝xauth授權。- 斷開ssh連接,使用
ssh -AX username@ip地址
重新連過來,-A的意思是使用X11認證授權方式,這樣連接之后,linux主機會生成一個~/.Xauthority
保存授權允許連接的遠程終端信息。 echo $DISPLAY
可以顯示當前xauth自動生成的顯示端口,比如我這里是:ubuntu:10.0
,ubuntu是我的linux主機名,其實在我這里ubuntu跟localhost是一樣的。- 再次嘗試執行x11應用,比如xclock,應當能成功了。
- 以后連接遠程主機的時候,使用
ssh -X ...
或者ssh -Y ...
而不用增加-A選項了,我們使用-A只是為了生成~/.Xauthority
授權文件。