1. 程式人生 > >Linux 桌面玩家指南:10. 沒有 GUI 的時候應該怎麼玩

Linux 桌面玩家指南:10. 沒有 GUI 的時候應該怎麼玩

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

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

前言

前一篇講了 X Window,這一篇就來講講沒有 X Window 的 Linux,主要是 Linux 的字元模式,甚至是在進入 Linux 之前的 Grub 命令列模式。本來想把這一篇的標題叫《字元介面怎麼玩》,或者《沒有圖形介面怎麼玩》,但是怎麼想都覺得不準確。去掉桌面環境的 Linux,並不一定就不是圖形介面,因為 Linux 圖形介面無處不在。以前我使用 Linux 桌面的時候,總是有一個誤區:認為只有 XServer 啟動後,才能夠訪問到圖形系統,否則只能訪問字元介面。隨著對 Linux 的認識逐步加深,才發現即使在 XServer 啟動之前,圖形介面也是無處不在的。例如,Grub 的系統啟動選單,可以是圖形化的,還可以通過改背景和主題進行美化。再例如在 Linux 初始化過程中,有一個 PlyMouth 軟體,可以直接通過核心的 DRM 模組訪問圖形硬體,從而顯示一個圖形化的啟動介面和進度條,同理,PlyMouth 也是可以通過更改主題進行美化的。最後,當 Linux 初始化完成後,會給我們顯示一個讓我們登入的圖形介面,這就是 DM(Display Manager),這個 DM 既是 XServer 的父程序,負責啟動 XServer,又是一個 XClient,給出圖形化的登入介面。登入成功後,它又是 Gnome Shell 的父程序,負責啟動 Gnome Shell。還有,即使在純字元介面下,也是可以使用 FrameBuffer 獲得圖形功能的,甚至可以截圖和播放視訊。唯一的區別,就是在這些模式下,在沒有桌面環境的情況下,我們和計算機的互動,往往只能通過 CLI 進行。所以,我給這一篇取名《沒有 GUI 的時候應該怎麼玩》。

逆天的 GRUB

Linux 系統啟動的過程是這樣的:先由 BIOS 啟動一個系統載入程式;然後系統載入程式負責把 Linux 的核心載入到記憶體,同時把 initrd 載入到記憶體,然後把控制權交給 Linux 的核心;Linux 的核心初始化完成後,將控制權交給 init 程式;init 程式負責啟動各種服務。如果要啟動圖形桌面系統,則 init 先啟動一個視窗管理器,由視窗管理器負責使用者的登入和驗證;使用者登入和驗證成功後,視窗管理器負責啟動 X 伺服器和客戶端,進入桌面系統。如果是不需要圖形桌面系統的 Linux,則 init 啟動 login 程式,login 程式負責使用者的登入和驗證,驗證成功後,啟動一個 shell。

GRUB 就是目前 Linux 系統使用的系統載入程式,是計算機啟動後執行的第一個程式(當然,BIOS除外)。它在將 Linux 核心載入到記憶體的時候,還可以向核心傳遞各種引數。目前的 Linux 發行版使用的 GRUB 都已經是第 2 版了,它的功能和配置都和以前的版本不一樣。網上很多文章都是基於以前的 GRUB Legacy 版本進行的講解,已經不能適應現在新的形勢了。

GRUB 的文件在這裡:https://www.gnu.org/software/grub/manual/grub/。從前面的介紹可以看出,GRUB 是計算機啟動後執行的第一個程式,這個時候 Linux 的核心還沒有載入,其它的程式也都不可能執行。這時有人就會想了,這個 GRUB 的功能應該相當有限吧。我剛開始也是這麼想的。但是當我讀完前面給出的 GRUB 文件後,我的思想被徹底顛覆了。GRUB 的功能太 TM 強了,簡直逆天。

那麼這個一開機就啟動的簡單程式究竟具有哪些讓人意想不到的功能呢?請看我列舉幾條:

  • 能夠訪問任何裝置上的資料,不管你是硬碟、軟盤還是光碟;
  • 能夠探測到所有的記憶體;
  • 能夠識別大部分的檔案系統,不管你是 FAT32、NTFS 還是 ext2/ext3/ext4;
  • 能夠識別檔案系統中的檔案,文件中說它可識別大部分可執行檔案格式,ELF什麼的根本不在話下;
  • 能夠使用 .png、.jpg 格式的圖片作為背景,說明它能夠識別一些圖片格式;
  • 對字型的支援稍微差一點,好像只能使用 PFF2 格式的字型;
  • 當然可以讀取和輸出硬碟上的文字檔案;
  • 據說還能播放樂曲;
  • 支援聯網,可以從網路上啟動作業系統;
  • 可以支援串列埠輸入輸出。

這些功能真的是已經超強了,就快趕上一個作業系統了。重要的是,它還提供了一個非常好用的命令列介面,該命令列介面的使用方法和 Linux 系統中的 Shell 極其接近,也支援程式設計、支援環境變數,其程式設計的語法也和 Bash 差不多。再加上 GRUB 提供的豐富的命令,該介面使用起來爽得不要不要的。

GRUB 實戰

實踐出真知,下面以 Ubuntu 為例開始實戰。

GRUB的介面

剛安裝好的 Ubuntu 啟動時不顯示 GRUB 介面,因為它在設定中把它隱藏了。它的啟動畫面是這樣的:

必須按一下 ESC 鍵,我們才能夠看到 GRUB 的選單,它是這樣的:

上面這個介面想必大家已經很熟悉了。在這個介面中,如果按下 c 鍵,就會切換到 GRUB 的命令列介面,如下:

還有一種情況就是,如果大家在使用 Linux 過程中不小心刪除了 /boot/grub/grub.cfg,或者配置錯誤,或者刪除了 Linux 系統所在的硬碟分割槽的資料,使得 GRUB 無法正確載入 Linux 系統,也會自動進入到這個命令列介面。

GRUB 支援的命令

GRUB 的命令補全功能非常方便,只要按一下 TAB 鍵,就可以顯示它支援的所有命令。命令之後按 TAB 鍵,可以自動補全檔名。下面是 GRUB 支援的命令,我按 TAB 鍵調出來的:

使用ls命令可以列出目錄和檔案,使用cat命令可以輸出文字檔案的內容。在 GRUB 中,使用(hd0, msdos1)或者(hd0, gpt1)識別硬碟分割槽,使用(hd0, gptN)/boot/grub/grub.cfg這樣的形式識別檔案。由於 GRUB 能自動識別根分割槽,所以我下面的命令中省略掉了指定硬碟分割槽的部分。如下圖:

在上圖中,我使用cat /etc/fstab命令顯示了我係統中硬碟分割槽的情況。可以看到,我使用的是 GPT 分割槽格式和 EFI 韌體,硬碟分了三個去,第一個分割槽的掛載點是/boot/efi,並且是 vfat 格式的檔案系統,第二個分割槽的掛載點是根目錄/,第三個分割槽是 swap 空間。按照 GRUB 的術語,則分割槽(hd0, gpt1)是掛載的/boot/efi,分割槽(hd0, gpt2)是根目錄,分割槽(hd0, gpt3)是交換分割槽。可以看到,GRUB 中硬碟是從 0 開始計數的,而分割槽是從 1 開始計數的。

GRUB 的環境變數

我在之前的某一篇隨筆中講過,命令列引數、環境變數、配置檔案是對軟體進行配置的三駕馬車,GRUB 也不例外,它的很多行為也受環境變數控制。下面看一個例子,當我想檢視 GRUB 的啟動配置檔案/boot/grub/grub.cfg時,使用cat命令檢視該檔案的內容,但是由於該檔案太長,一個螢幕顯示不完,所以只能看到最後幾行,如下兩圖:

這是非常蛋疼的,但還不是最鬱悶的,畢竟/boot/grub/grub.cfg是系統中的一個檔案,大不了我進 Linux 後用 vim 看。最蛋疼的是某些命令的輸出,只能看到最後幾行,又不能儲存下來,真的讓人捉急。就像下面這個例子,我使用videoinfo命令檢視我的 GRUB 支援哪些圖形解析度:

這個時候,就只能通過設定環境變數的方法來解決問題了。使用set pager=1命令設定環境變數pager,讓 GRUB 的輸出啟用分頁,如下圖:

我們還可以通過不帶引數的set命令顯示所有可用的環境變數,如下圖:

也可以使用echo命令輸出某一個環境變數,如下圖:

更改解析度

我們可以控制 GRUB 顯示介面的解析度,還可以通過 GRUB 控制 Linux 啟動進入字元模式後的解析度。前提條件是要看我們的 BIOS 和顯示卡支援哪些模式。可以通過 videoinfo命令檢視,如下圖:

我使用的是虛擬機器,因為玩 GRUB 不使用虛擬機器無法截圖啊。如果採取的是 EFI 韌體,則其輸出如下:

如果採取的是 Legacy BIOS,則其輸出如下:

可以看到,如果使用的是 Legacy BIOS,它的顯示模式是由 ' VESA BIOS Extension Video Driver ' 提供支援的。如果使用的是 EFI,則其顯示模式是由 ' EFI GOP driver ' 提供支援的。在我的虛擬機器中,它們能提供的最高解析度也只有 1152 x 864,遠遠達不到 1920 x 1080。但是在我的物理機中,都是可以達到 1920 x 1080。而且貌似只能進入 1920 x 1080,想改小還改不了。在物理機上,想通過改小解析度,然後利用顯示器的放大功能來放大字型的夢想是破滅了的。

在虛擬機器中,我要做的是把解析度改大,至少讓我完全進入 Linux 字元介面的時候有個 1024 x 768 的解析度吧,不然字元介面用起來豈不是太憋屈。可以通過修改 /etc/default/grub檔案,然後呼叫sudo update-grub命令更新 GRUB。如下圖,使用sudo vim /etc/default/grub修改配置檔案:

在上面的這個檔案中的註釋裡,也寫得很明白了,要修改 GRUB 和 Linux 字元介面的解析度,可以通過修改 GRUB_GFXMODEGRUB_GFXPAYLOAD_LINUX 引數來設定,而且千萬不要設定GRUB_TERMINAL=console,不然就真的進入只有文字的文字模式了,沒有 Graphic 的支援,還談啥解析度呢。

然後重啟系統,可以看到我們的 GRUB 介面變大了一圈,如下兩圖:

下面進入 Linux 的字元介面,進入 Linux 字元介面的方式是啟動進入 Linux 後,使用 sudo systemctl set-default multi-user.target,然後重啟,在 1024 x 768 的解析度下開一個 vim 看看,如下圖:

又找到了懷舊的感覺,不是嗎?唯一的缺憾是字太小。如果是在我的物理機上,15.6寸 1920 x 1080 的螢幕,字會小得根本無法看。下面,我們再來探討 Framebuffer 的正確開啟姿勢。

Linux 純字元模式和 Framebuffer

Linux 純字元介面的用途

  1. 裝逼必備
  2. 省資源,伺服器一般不安裝圖形介面
  3. 圖形介面崩潰後緊急救援

進入字元介面的正確方式

目前新的 Linux 發行版基本上都使用 Systemd 作為 init 程式,不再使用 SysV init 和 Upstart init。所以如果想讓系統啟動後直接進入字元介面,應該使用如下命令:

sudo systemctl set-default multi-user.target

反過來,要讓系統啟動後直接進入圖形介面,應該使用如下命令:

sudo systemctl set-default graphical.target

另外,Linux 本身提供有虛擬控制檯的功能,使用Ctrl + Alt + F1Ctrl + Alt + F7進行切換,其中有一個是圖形介面,剩下的是字元介面。圖形介面玩崩潰了,就不得不使用Ctrl + Alt + F3切換到字元介面進行救援。

關於 Framebuffer

字元介面分兩種,一種是不開啟 Framebuffer 的,另一種是開啟 Framebuffer 的。Framebuffer 是一種圖形驅動,不開啟 Framebuffer 就是真的全字元,不能改變解析度,不能顯示影象,不能截圖。目前最新的 Linux 發行版預設開啟 Framebuffer。控制 Framebuffer 開啟和關閉,以及解析度的方法,是設定 Grub2 的引數。修改 /etc/default/grub檔案,新增如下引數可以設定解析度:

GRUB_GFXPAYLOAD_LINUX=1024x768x32

然後使用如下命令更新 GRUB2 配置:

sudo update-grub

其中的解析度必須是我們的硬體支援的。可以通過 GRUB2 命令列中的videoinfo命令檢視我們的硬體支援的解析度。

如果要關閉 Framebuffer,則這樣更改 GRUB2 的配置:

GRUB_GFXPAYLOAD_LINUX=text

同樣,需要:

sudo update-grub

然後重啟。

字元介面下聯網

以前在圖形介面的時候,設定個網路、連線個 wifi 非常簡單,玩兒似的,結果一進入純字元介面就抓瞎。不聯網,就不能下載和安裝軟體包,後面就玩不下去了。所以進入純字元介面後,要解決的第一件事就是怎麼聯網。說到管理網路的工具,大家可以列舉一大堆,什麼 ipconfig、iwconfig、ip 等等。但是,在最新的 Linux 發行版中,已經是使用 NetManager 管理網路了。通過閱讀 NetManager 的文件,可以知道它提供一個功能很強大的命令列工具,那就是 nmcli。通過man nmcli可以檢視該工具的用法。如下圖:

使用如下命令可以檢視可用的 wifi 熱點以及連線 wifi:

nmcli device status                                         #檢視網路連線的狀態,可以看到各網絡卡的名稱
nmcli device wifi list iface 網絡卡名稱                 #檢視可用的 wifi 熱點
nmcli device wifi connect **** password ****   #連線 wifi,需要提供 wifi 的名稱和密碼

如下圖:

連上了網,Ubuntu 就可以在純字元介面下起飛了。

使用 fbterm

通過上面的截圖,發現兩個問題:

  1. 在我的 1920x1080 的膝上型電腦螢幕上,預設的字實在是太小;
  2. 不能顯示中文,上圖中 wifi 熱點名稱含有中文的,都顯示不出來。

解決辦法是使用 fbterm。一舉解決字型大小問題和中文顯示問題。先安裝 fbterm,使用如下命令:

sudo apt-get install fbterm

先使用sudo fbterm啟動 fbterm 一次,再用exit命令退出,這樣,fbterm 會自動生成一個預設的配置檔案~/.fbtermrc,然後修改~/.fbtermrc配置檔案中的兩行,設定使用的字型和字型大小,如下:

font-names=DejaVu\ Sans\ Mono
font-size=16

然後使用sudo fbterm命令啟動 fbterm,就可以了。下面是看對比圖,使用 fbterm 之前,Vim 的啟動介面是不能顯示中文的:

使用 fbterm 之後,中文可以正常顯示:

使用 fbterm 之前,閱讀程式碼是這樣的:

字非常的小,NERDTree 和 Tagbar 裡面的符號顯示也有問題。使用 fbterm 之後,就很漂亮了,如下圖:

這才是全高清屏該有的顯示效果嘛。關於在 fbterm 下輸入中文,我嘗試過 fbterm-ucimf,也嘗試過 fcitx-frontend-fbterm,都沒有成功。後來我就不試了,反正我也沒有在全字元介面下輸入中文的需求。

顯示 Framebuffer 的資訊

使用 fbset 可以檢視 Framebuffer 的資訊,包括 Framebuffer 是否開啟,解析度是多少,由哪個核心模組提供支援等。使用如下命令安裝 fbset:

sudo apt-get install fbset

使用sudo fbset -i命令檢視 Framebuffer 的資訊,如下圖:

在 Framebuffer 下截圖

使用 fbgrab 可以在 Framebuffer 下進行截圖。使用如下命令安裝 fbgrab:

sudo apt-get install fbgrab

使用 fbgrab 命令的方式如下:

sudo fbgrab -c N filename.png      #對 /dev/ttyN 對應的終端進行截圖
sudo fbgrab -C N filename.png     #先跳轉到 /dev/ttyN 對應的終端,再進行截圖
sudo fbgrab -s N filename.png      #先等待 N 秒,再進行截圖

我前面的圖片都是使用 fbgrab 截的,這裡就不貼圖了。

在 Framebuffer 下檢視圖片

使用 fbi 可以在 Framebuffer 下檢視圖片,同樣使用sudo apt-get install fbi安裝這個軟體。在看圖介面下按 H 鍵,還會顯示幫助資訊。如下圖:

在純字元介面下上網

使用老牌的上網工具 w3m,安裝方式sudo apt-get install w3m,然後使用w3m https://www.cnblogs.com/就可以訪問部落格園了,只有文字哦,圖片就不要想了。效果如下圖:

當然,必須在 fbterm 下執行才能顯示中文。

視訊播放

使用 mplayer 播放器可以播放視訊,通過mplayer -vo help命令可以看到,mplayer 支援很多種視訊驅動,而 Framebuffer 正是其中一種。使用sudo mplayer -vo fbdev2 badapple.mp4播放 Bad Apple 的 PV 視訊,效果如下:

因為這裡要錄製 gif 動畫,所以我使用了虛擬機器執行 Linux,Framebuffer 的解析度設定為 1024x768。同樣,通過上面的mplayer -vo help命令,還可以看到 mplayer 支援使用 libaa 庫,將視訊播放為字元畫。據我觀察,只有在圖形介面下效果才可以,純字元介面不行。使用mplayer -vo aa -moniterpixelaspect 0.5 badapple.mp4播放,效果如下:

屏保和裝逼

當然是 cmatrix 啦。效果如下:

求打賞

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

版權申明

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