1. 程式人生 > >Linux 桌面玩家指南:09. X Window 的奧祕

Linux 桌面玩家指南:09. X Window 的奧祕

特別說明:要在我的隨筆後寫評論的小夥伴們請注意了,我的部落格開啟了 MathJax 數學公式支援,MathJax 使用$標記數學公式的開始和結束。如果某條評論中出現了兩個$,MathJax 會將兩個$之間的內容按照數學公式進行排版,從而導致評論區格式混亂。如果大家的評論中用到了$,但是又不是為了使用數學公式,就請使用\$轉義一下,謝謝。

想從頭閱讀該系列嗎?下面是傳送門:

前言

大名鼎鼎的 X Window 大家肯定不陌生。都知道它是 Unix/Linux 下面的視窗系統,也都知道它基於 Server/Clinet 架構。在網上隨便搜一搜,也可以找到不少 X Window 的介紹。有不少文章為了給使用者留一個直觀的印象,往往先讓系統進入純文字介面,然後使用 startx 來啟動圖形介面,或者直接使用 X 來啟動 X Server,再然後執行一個 xterm 來做示範。我覺得以上這些文章對 X Window 的理解有限,不夠深入。所以,我這裡寫一篇《X Window 的奧祕》,以最新的 Ubuntu-18.10 Desktop 為例,展示如何學習 X Window。

10 月是一個比較開心的月份。在這個月中,陸續釋出了最新的 Ubuntu 18.10 和 Fedora 29,還有人在我的部落格中問關於 CentOS 7 的問題。CentOS 7 固然是一個優秀的發行版,但並不是作為桌面系統的首選,Gnome 的版本太舊,官方倉庫中的軟體包也不夠豐富,美化起來比較困難。在這一篇中,我要展示遠端連線 X Server 的操作,需要兩個外觀差距稍微大一點的 Linux 桌面系統,所以選擇了 CentOS 7 和 Ubuntu 18.10。

Ubuntu 18.10 這次外觀大變樣,使用了 Yaru 主題,下面的截圖展示了其中 Terminal 和 GVim 的外觀:

而 CentOS 7 預設的外觀太醜了,所以我給他換上了最流行的 adapta-gtk-theme 和 paper-icon-theme,下面的截圖展示了其中 Terminal 和 GVim 的外觀:

這兩種風格應該是比較好區分的,在後文中,很容易通過外觀來判斷一個 GUI 程式究竟來自於哪一個系統。

瞭解自己機器上的 X Window

X Window 其實是一種規範,它有很多不同的實現,在 Linux 系統下最流行的是實現 Xorg 和 XFree86,微軟 Windows 系統下也有 X Window 的實現,蘋果的Mac 也是 X Window 的一種。要了解自己機器上執行的 X Window 究竟是哪一個,可以使用檢視程序的ps命令,如下圖:

從上圖可以看出,Ubuntu 18.10 使用的 X Window 是 Xorg。如果使用 ps -ef 命令,還可以看到 Xorg 執行時的命令列引數。

想了解 X Window,下面這些文件需要看一遍先:

下面來說一下也許是眾所周知的基礎知識:X Window 是一個分層的架構,它分為 Serve 和 Client。X Server 負責圖形介面的顯示,(也負責使用者的輸入),而Client 程式需要連線到 X Server,然後請求 X Server 繪製圖形介面,同時從 X Server 接受使用者的輸入。在桌面系統上,X Server 和 Client 程式往往安裝在同一臺機器上,日常使用基本感覺不到它是分層的。但是很顯然,X Server 和 Client 也可以分別執行在不同的機器上,在一臺機器上執行程式,而在另外一臺機器上顯示圖形介面。

X Window 中的 Server 和 Client 的概念和我們平時接觸到的“Server/Client”概念剛好相反。很多熟悉 Internet 原理的人,第一次接觸 X Window 的這兩個概念都會搞錯。比如,我在一臺本地機器上執行 Ubuntu 18.10 桌面版,而在另外一臺遠端機器上執行 CentOS 7(純字元介面),當我用 ssh 從 Ubuntu 連線到 CentOS 的時候,Ubuntu 是 Client,而 CentOS 是 Server。在 X Window 中,Server 偏偏是我面前的這臺 Ubuntu,X Server 執行在 Ubuntu 上。我可以在 CentOS 中執行 GVim,但是視窗顯示在 Ubuntu 中,這時,GVim 是一個 Client 程式,它在遠端機器上執行,而它的視窗顯示在本地。

理解 display 和虛擬控制檯

前面提到網上很多介紹 X Window 的文章都是先讓系統進入字元介面,然後手動啟動一個 X Server。其實這完全沒有必要,因為在同一臺機器上完全可以執行多個 X Server,只需要讓每個 X Server 的 display 不同即可。那麼 display 究竟是什麼?

在 X Window 中,可以通過 hostname:display_number.screen_number 來指定一個螢幕。可以這樣理解:一臺計算機可以有多個 display,一個 display 可以有多個螢幕。所以,display 相當於是計算機配備的一套輸入輸出裝置,一般情況下,一臺電腦只配一套鍵盤滑鼠和一個顯示器,特殊情況下,可以配多個顯示器。

現在問題出來了,我的電腦只有一套鍵盤滑鼠和一個顯示器,也就是隻有一個 display,那又怎麼能執行多個 X Server 呢?那是因為在 Linux 中,還有虛擬控制檯這樣的高階特性。只需要同時按下 Ctrl+Alt+F1、Ctrl+Alt+F2、...、Ctrl+Alt+F7,就可以在不同的虛擬控制檯中進行切換。在 Ubuntu 18.10 中,虛擬控制檯 3 到 6 執行的是 agetty,也就是字元介面,虛擬控制檯 2 執行的是 Xorg。(Fedora 中不一樣,虛擬控制檯 1 執行的是圖形介面,其它的是字元介面。)如下圖:

我們可以直接執行 X Server 程式來啟動 X Server。/usr/bin/X 和 Xorg 都是 X Server 程式。其實 /usr/bin/X 是 Xorg 的符號連結,用哪一個都是一樣的。

啟動 X Server 的時候可以指定 display 引數,因為可以省略掉 hostname 和 screen_number,所以可以用 :0,:1 這樣的格式來指定 display。在我的機器上,本來就有一個 X Server 在執行,display :0 已經被佔用了,所以我使用 sudo X vt8 :1 -auth /run/user/1000/gdm/Xauthority -retro 來在 display :1 上再執行一個 X Server,如下圖:

其中的 -retro 引數是為了讓 X Server 的背景顯示為斜紋,否則背景為純黑色,那就看不出來是否啟動了 X Server。vt8 引數指定將新啟動的 X Server 放到第 8 個虛擬控制檯。:1引數指定新啟動的 X Server 的 display number。啟動 X Server 後的效果如下圖:

按 Ctrl+Alt+F2 回到 display :0,在新啟動的 X Server 中執行一個 GVim 看看效果。執行 GVim 時,使用 -display :1 引數指定視窗顯示在新啟動的 X Server 上,使用 -geometry 引數指定視窗的大小和位置。

再按 Ctrl+Alt+F8 切換到 display :1,看效果。如下:

不知道為什麼,在 Ubuntu 18.10 中的虛擬控制檯中切換兩下,新啟動的 X Server 就自動關閉了。而且切換到虛擬控制檯 8 再切換回來,我的 Ubuntu 桌面的解析度也變成了 800x600,非常不爽。當然,這裡的展示只是為了證明能在一臺機器上執行兩個 X Server,能看到效果就行。

遠端連線 X Server

前面展示的在一個系統中執行兩個 Xorg 並不是很吸引人,畢竟新啟動的 X Server 太醜了,而且 Xorg 的引數一大堆,不是很容易搞。既然 X Client 和 X Server 可以分佈在不同的機器上,那麼,如果我們能夠把別的系統中的 GUI 程式顯示到本地機器中,那就比較過癮了。理論上講,如果在前面提到的 CentOS 7 中執行gvim -display 192.168.40.135:0命令(這裡的 192.168.40.135 是 Ubuntu 18.10 系統的內網 IP),就應該可以把介面顯示到 Ubuntu 18.10 桌面上,反之,如果在 Ubuntu 18.10 中執行gvim -display 192.168.40.130:0命令(這裡的 192.168.40.130 是 CentOS 7 系統的內網 IP),就可以把介面顯示到 CentOS 7 中。

但是,這是行不通的。行不通的原因首先是 Xorg 複雜的認證機制。如果沒有認證機制把關,隨便就能讓別的系統把圖形介面甩過來,那桌面上豈不是垃圾視窗滿天飛嗎?其次,Xorg 在啟動時往往會帶上-nolisten tcp引數,禁止接受從 TCP/IP 網路上傳過來的連線請求。要禁用該選項,往往需要去更改 gdm 的配置檔案。

我這裡就不折騰這些複雜的認證機制和命令列引數了,我這裡來點簡單的。最簡單的把遠端機器上的圖形介面帶回本地桌面的方式,是使用 SSH 的 X11 Forwarding 功能。該功能用起來非常簡單,只需要在使用ssh命令連線遠端機器的時候,加上-X或者-Y引數就可以了。如下圖,我在 Ubuntu 18.10 中使用ssh -X 192.168.40.130遠端連線到 CentOS 7 中,然後再執行gvim命令,該 GVim 視窗就在 Ubuntu 桌面中顯示出來了。

反之,如果在 CentOS 7 中使用ssh -X 192.168.40.135遠端連線到 Ubuntu 18.10 中,在執行gvim命令,就可以把 Ubuntu 中的 GVim 顯示到 CentOS 7 的桌面中,如下圖:

SSH 的 X11 Forwarding 是一個非常強大的功能。我們甚至可以把 Linux 中的圖形介面顯示到 Windows 中,只需要在 Windows 中執行一個 X Server 就可以了。我選擇的軟體是 XMing,然後使用 PuTTY 連線到 Linux 系統。在 PuTTY 的設定中,開啟 X11 Forwarding 功能,如下圖:

然後可以把 Linux 桌面中的圖形介面帶入 Windows 桌面,如下圖:

理解 DisplayManager 和 X Window 桌面環境的啟動過程

X Server 的啟動方式有兩種,一種是通過顯示管理器啟動,另一種是手動啟動。在前面的例子中,我通過直接執行sudo X vt8 :1 -auth /run/user/1000/gdm/Xauthority -retro來啟動了一個 X Server,這就是手動啟動。手動啟動 X Server 的方法還有執行 startx 或者 xinit。手動啟動 X Server 的缺點就是啟動的 X Server 不好看。而顯示管理器啟動的不僅有 X Server,還有一大堆的 Client 程式,構成了一個完整的桌面環境,介面當然就漂亮多了。

顯示管理器(Display Manager)是什麼呢?前面我講到 display 就是一個電腦配備的一套鍵盤滑鼠和顯示器,那麼顯示管理器就是這一套裝置的管理器了。顯示管理器可以直接管理這些裝置,所以它可以控制 X Server 的執行,由它來啟動 X Server 那是再合適不過了。系統啟動過程是這樣的:核心載入-->init程式執行-->顯示管理器執行--> X Server 執行-->顯示管理器連線到 X Server,顯示登入介面-->使用者登入後,登入介面關閉,載入桌面環境。從上面的流程可以看出,顯示管理器是 X Server 的父程序,它負責啟動 X Server,當 X Server 啟動後,它又變成了 X Server 的一個 Client 程式,連線到 X Server 顯示歡迎介面和登入介面,最後,顯示管理器又是所有桌面環境的父程序,它負責啟動桌面環境需要的其它 Client 程式。

在 Ubuntu 的早期版本中,使用 lightdm 取代了傳統的 xdm、gdm 等顯示管理器。從 Ubuntu 17.10 開始,Ubuntu 放棄了 Unity 桌面而回歸 Gnome 3,則顯示管理器又變回 gdm 了。

可以使用不同的方法對 X Server 進行配置,前面的例子是直接指定命令列引數。除了指定命令列引數,還可以使用環境變數和配置檔案。X Server 的配置檔案為一般是 /etc/X11/xorg.conf 或 /etc/X11/xorg.conf.d/ 目錄下的 .conf 檔案,當然,配置檔案也可以放在其它的目錄中,具體資訊,請參看 man xorg.conf。

如果沒有配置檔案,X Server 將在啟動的時候自動檢測硬體,然後生成一個內建的配置。Ubuntu 系統就沒有配置檔案。不過沒關係,如果需要使用配置檔案的時候,可以通過 X Server 的 -configure 引數生成一個配置檔案,裡面包含當前自動檢測出的配置。如果需要任何個性化的配置,對該檔案進行修改即可。

執行巢狀的 X Server

我們上面執行的 X Server 都是直接佔用了計算機的整個顯示器和鍵盤滑鼠,事實上,在現有的圖形介面中,還可以以視窗模式執行另外一個 X Server,稱為 nested X Server。最常用的 nested X Server 是 Xephyr,在 Ubuntu 中可以通過如下命令安裝它:

sudo aptitude install xserver-xephyr

Xephyr 的使用非常簡單,可以通過man Xephyr命令檢視它的使用手冊。如果輸入Xephyr :1 -screen 1024x768命令,就可以在現有圖形介面中開啟一個視窗模式的 X Server,其中-screen引數用來指定 X Server 顯示區域的大小。以後再啟動 GUI 程式,就可以通過程式的 -display :1 選項讓程式執行在這個巢狀的 X Server 中,如下圖:

怎麼樣,是不是很好玩呢?除了好玩,還很有用,比如除錯視窗管理器啊、連線遠端桌面啊什麼的都用得著。當然,我這裡只是簡單展示一下原來 X Window 還可以這麼玩。

總結

1.在一個 Linux 系統中存在多個虛擬控制檯,所以可以啟動多個 X Server;

2.啟動 X Server 的方式有兩種,一種是使用 /usr/bin/X、startx、xinit 手動啟動,一種是通過顯示管理器啟動;

3.遠端計算機連線本地的 X Server,需要 X Server 開放 TCP 埠,還要搞定安全認證;

4.如果覺得搞定 X Server 的 TCP 埠和安全認證太麻煩,可以使用 SSH 的 X11 Forwarding 功能,遠端連線 X Server 超級方便;

5.X Server 的配置,可以通過命令列引數,可以通過環境變數,還可以通過配置檔案;

6.可以在現有的圖形介面下以視窗模式執行巢狀的 X Server,常用的軟體是 Xephyr;

7.使用 XMing 和 PuTTY,把 Linux 圖形介面帶入 Windows 不是夢。

求打賞

我對這次寫的這個系列要求是非常高的:首先內容要有意義、夠充實,資訊量要足夠豐富;其次是每一個知識點要講透徹,不能模稜兩可含糊不清;最後是包含豐富的截圖,讓那些不想裝 Linux 系統的朋友們也可以領略到 Linux 桌面的風采。如果我的努力得到大家的認可,可以掃下面的二維碼打賞一下:

版權申明

該隨筆由京山遊俠在2018年11月01日釋出於部落格園,引用請註明出處,轉載或出版請聯絡博主。QQ郵箱:[email protected]