Linux 新手入門教程 1991年10月5日, Linus Torvalds 在互聯網上發佈消息,宣佈他自己開發的內核系統誕生了。他將內核源代碼保存在芬蘭最大的 FTP 網站上,命名為 Linux ,取義 ,並向全世界所有人公佈。這也使得10月5日成為一個特殊的日子,以致之後的許多 Linux 版 ...
目錄
Linux 新手入門教程
1991年10月5日,Linus Torvalds 在互聯網上發佈消息,宣佈他自己開發的內核系統誕生了。他將內核源代碼保存在芬蘭最大的 FTP 網站上,命名為 Linux,取義
Linus's Minix
,並向全世界所有人公佈。這也使得10月5日成為一個特殊的日子,以致之後的許多 Linux 版本都選擇在這個日子發佈。當然,如今的 Linux 一詞被遞歸定義為Linux is not Unix
。
簡介
Linux 是一套免費使用和自由傳播的類 Unix 操作系統,嚴格來說,Linux 一詞僅指其操作系統內核,不包括任何附加軟體。但如今 Linux 擁有數不勝數的發行版本,廣義上它們都可以叫做 Linux,典型代表如 Debian 系列、RedHat 系列、Arch 系列和 SUSE 系列等,它們也都有著各自的側重和堅持。
桌面環境
儘管我們使用 Windows 或 OS X 操作系統的時候可能不會很在意桌面環境
,但在 Linux 下我們將需要考慮選擇一個中意的桌面環境——也許是多個——或者在某些情況下,完全不必安裝桌面環境,這是非常靈活且自由的。桌面環境可能是由大量組件構成的完整套件,也可能僅僅只是一個簡單的視窗管理器,但無論如何,它們的核心目標都是為用戶提供一個直觀易用的可視化環境和視覺工作區。著名的大型桌面環境 Gnome 和 KDE 提供了傑出的圖形表現和豐富的功能組件,輕量桌面環境如 Xfce、mate 和 lxde 等也算是“麻雀雖小,五臟俱全”,更有其他一些專註簡潔、美觀或是高效的桌面環境可選,因此我們說 Linux 的桌面環境的選擇是“靈活且自由”的。
Linux 系統內核並不包括圖形服務。想要使用圖形環境,必須先安裝 X11
,即 X Window 系統,它是最早應用於傳統 Unix 系統的圖形用戶介面,工作於內核與桌面環境之間。這使得 Linux 擁有豐富的桌面環境以供選取。儘管桌面環境可能有風格迥異的設計,但大體上都應包括登錄管理器、視窗管理器、應用啟動器等組件,可能還包括一套開箱即用的軟體套件,如編輯器、瀏覽器和終端模擬器等。大部分情況下,在使用桌面發行版的安裝鏡像正確安裝系統後,桌面環境都已經預裝並正常工作了。
Linux 的安裝
這裡以 Manjaro 操作系統為例,簡要說明系統安裝步驟
從 Manjaro 官網 的下載頁面選擇合適的版本並將
iso
鏡像文件下載到本地(以 KDE 版本為例)。如果使用虛擬機,則此時新建一個虛擬機,將剛纔下載的
iso
鏡像裝載到虛擬機上啟動;若要通過U盤安裝到本地機器,則可用 Rufus 軟體載入鏡像並以DD
模式寫入U盤,然後重啟電腦,註意正確設置 BIOS 以從U盤啟動。在 Manjaro 的啟動頁面進行相關設置,若在接下來的步驟中出現驅動問題,可重回此步並將
driver
項設為non-free
。進入
live
系統後,啟動安裝程式,按照提示配置好各項參數,最後點擊安裝即可。安裝完成後,重啟電腦並移除U盤,在 Grub 頁面選擇剛剛安裝的 Manjaro 操作系統。
文件系統和分區
Linux 使用的磁碟分區格式為 ext4
,而 Windows 並不支持(不會顯示在資源管理器中)這種格式,因此對於雙系統的用戶來說,Linux 系統所占用的磁碟空間需要合理分配。Linux 將文件系統組織為一個樹形結構,與 Windows 以盤符區分的方式有所不同,Linux 的所有目錄都是 /
目錄的子目錄,這個 /
目錄稱為根目錄。對於管理多個分區的 Linux 來說,它將各個磁碟分區掛載
到不同的目錄下,分區的所有文件目錄都通過掛載到的目錄來訪問,因此對於 Linux 文件系統來說,分區管理是透明
的。此外,對於U盤、CD等可移動介質,Linux 也是通過即時掛載、事後卸載的方式管理,這是 Linux 在文件系統上區別於 Windows 的一大特點。
Linux 普通文件系統分區格式一般用 ext4
,而用作交換區的 swap
分區則有專用的 swap
格式,提供與 Windows 虛擬頁面文件類似的虛擬記憶體功能,只不過 Linux 的做法更加徹底。這個分區的大小一般設為與物理記憶體大小相等。
我們剛纔提到,Linux 的目錄樹是從唯一的一個 /
目錄出發,這似乎預示著,Linux 不能如 Windows 那樣用不同的盤符來分隔不同種類的文件,但情況恰恰相反,由於 Linux 有掛載點這一說,雖然從文件系統層面上看,所有文件都組織在一個目錄樹下,但從物理分區上講,在目錄樹上的任一節點都可以掛載不同的分區,這就使得無論如何進行分區,Linux 的文件系統除了選擇一個節點掛載它們之外無需作出任何更改,並且可以實現多個 Linux 系統在某個節點共用同一份數據,或者在操作系統每次啟動時為它掛載不同的分區,從而實現每次運行時都可以使用不同的數據。
另外,在 Linux 的文件系統中,以 .
開頭的文件名被認為是隱藏文件,更特殊的,./
和 ../
分別意味著 當前目錄
和 上級目錄
,它們不是實際存在的文件,僅代表兩個入口。事實上,Linux 隱藏文件的設定並非為了對某些文件進行保密,而只是將不需要顯示在前臺的文件加上標記,它們通常是系統和一些軟體的資源文件或應用數據目錄,並且用戶不需要在前臺看到它們。
NFS - 網路文件系統,是一套可擴展、高性能、高質量的共用文件系統,只需從一個或多個伺服器上建立數據倉庫,多個客戶端即可通過用戶介面訪問數據並載入到本地空間,如同本地的可插拔文件系統一般。它與普通文件系統唯一的區別在於其 I/O 請求是跨越網路完成的。
運行級別
Linux 有運行級別的概念,目前來說定義了七種運行級別:
- 0 停機狀態
- 1 單用戶模式
- 2 多用戶模式(無 NFS)
- 3 完全多用戶模式
- 4 保留
- 5 X11 圖形伺服器模式
- 6 重啟狀態
這些運行級別分別對應著不同的服務組,這些服務項在開機時由 init
負責啟動,一般這些都存儲在 /etc/rc.d/rcN.d/
目錄下,但有些系統並不遵循這個標準——比如 Arch。一般來說,用戶常用的預設運行級別為3和5——作為伺服器時通常為3,作為桌面操作系統通常使用5——當我們需要執行一些特殊操作時,可能需要手動進入單用戶狀態,如重置 root
用戶密碼等。
註:
若要恢復刪除的系統文件,請進入救援模式而不是單用戶模式,因為單用戶模式也需要從硬碟引導啟動!
不要將系統預設啟動狀態設為0或6,否則系統將無法正常啟動,切記!
強大的終端
Linux 系統的一個非常重要的工具就是 shell,它是 Linux 用戶操作電腦的橋梁,其本質是一個命令解釋器(CLI),文字模式下系統啟動後進入的界面就是 shell,而在圖形界面中通常要通過 終端模擬器
來進入。所謂終端,指的就是這種通過 shell 進行用戶交互的軟體。在 KDE 下,我們使用 Konsole 終端模擬器。著名的終端模擬器還有 Terminal、Yakuake 等。而選擇好終端模擬器後,我們還需要選擇一個 shell ——預設情況下,系統預設 shell 是 bash ——我的選擇是 Zsh。
前面提到,shell 是一個命令解釋器,那麼它的工作就很好定義了:接收用戶輸入的命令,執行它們,並輸出執行結果。這就是典型的 shell 的工作模式。shell 很多預置命令都由兩個字母構成——事實上,若非鍵盤上只有26個字母,可能現在的命令就只有一個字母了——這些命令能夠執行簡單的文件目錄管理。
# 切換工作目錄
cd ~/Documents
# 列出目錄下的文件/目錄列表
ls [-alh]
# 顯示當前工作目錄
pwd [-P]
# 更新文件的修改日期,一般用來創建文件
touch main.c
# 創建目錄
mkdir test
# 移動和複製文件,可用於重命名
mv a.c test/
mv a.c b.c
cp a.c a.c.back
# 刪除文件或目錄
rm a.c
rm -r test/
# 創建鏈接文件,類似 Windows 快捷方式
ln -s ~/Documents/clang
# 列出文件內容
cat a.c
# 回顯命令,可顯示環境變數
echo Hello, $HOME.'\n'This is my Path:'\n'$PATH
除了一些特殊命令外,shell 中運行的命令通常都是實際存在的程式,shell 會從用戶的 PATH
環境變數中定義的路徑查找命令並執行,路徑之間以 :
分隔。通常,PATH
環境變數並不包括 當前目錄
,因此,若要執行目錄下的程式,應以 ./
開頭。
作為命令解釋器,shell 除了能夠解釋執行用戶輸入的指令外,也能夠執行腳本文件。下例是一個典型的 shell 腳本:
#!/usr/bin/bash
# 我是註釋
# 巧了,我也是
echo "Currently working in `pwd`"
echo "Host: `hostname`"
ret=yes
ping -c 2 www.baidu.com > /dev/null || ret=no
echo "Am I online? $ret"
echo "Now running: $0"
figlet -f standard "The end."
要運行這個腳本,可以為它指定一個解釋器:
bash xxx.sh
也可以先賦予它 可執行許可權
,再直接執行:
chmod +x xxx.sh
./xxx.sh。
一個特殊的腳本是,shell
在用戶目錄下保存的名為 .bashrc
的文件(或 .zshrc
等),它是屬於 shell
的一個資源文件,這意味著每次啟動用戶的 shell
時,它都會預先尋找並分析此文件的內容,並執行相應的初始化命令。常見的用法包括在此文件中添加別名定義、添加環境變數配置等。
# ~/.bashrc
alias ll='ls -alF'
alias df='df -h'
export PATH=PATH:$HOME/.local/bin
Linux 文件系統許可權
對於任意一個目錄,執行 ls -hl
命令並觀察其輸出,我們將看到,每個項目之前都有一個由十位字元構成的字元串,這代表了一個文件(或目錄)的類型和許可權。其形式為 -rwxr-xr-x
,第一位代表類型(-/d/l/c/b/s/p),後面九位每三個一組,每位分別代表其讀、寫、可執行許可權,每組分別表示所屬用戶、所屬組和所有人的許可權。
Linux 中用戶與組的概念比 Windows 要深刻得多,除普通用戶外,最常涉及的是 root
用戶和 wheel
組。在 Linux 下,root
用戶是系統的最高管理員,擁有操作任何文件目錄的許可權,也就有著誤操作導致系統崩潰的風險,也可能因執行惡意程式導致系統被劫持,因此一般情況下,我們不會以 root
身份作業。但與此同時,很多任務又需要這些許可權才能執行,比如安裝應用或更改啟動項,於是 sudo
命令提出了一種普通用戶臨時獲取 root
許可權的可能,它允許用戶臨時獲取許可權來執行某些操作,並且可以配置用戶/組使用 root
身份可以執行哪些操作。一般情況下,作為桌面版用戶,我們也不必去細分這些許可權,所以可以簡單地將自己加入到 wheel
組即可擁有 sudo
的許可權,wheel
組正是預設的擁有 sudo
許可權的組。
軟體包管理
與 Windows 系統不同,儘管 Linux 也允許用戶直接運行可執行文件,但這些軟體通常會因為依賴問題等原因而不能正常工作。查找和安裝應用軟體最好的方式是通過軟體倉庫,不同的發行版通常會有不同的軟體倉庫,我們稱之為 源
,用來查找和下載安裝軟體包並解決依賴關係的工具稱為 包管理器
,如 Ubuntu 使用 apt
和 dpkg
,CentOS 使用 yum
和 rpm
,Manjaro 使用 pacman
等。
我們剛纔多次提及 依賴
,簡單來說就是指某個包使用了另一個包提供的介面,因而需要該包的支持才能運行,故安裝某個包可能同時需要為它安裝所有的依賴,卸載某個包又要考慮有沒有哪些包是依賴它而運行的,同時還要註意是否存在多個包依賴著同一個包的不同版本。這些檢查和操作是必要的,否則久而久之你將不知道自己的系統上哪些包是無用的,哪些是不可或缺的,也就不敢輕易安裝和卸載應用了。
用戶獲取軟體包的來源通常是官方或官方信任的鏡像站點,這些通常叫做軟體倉庫或 源
。作為天朝子民,為了加速軟體包的下載,我們往往會選擇國內的鏡像源,如清華源、中科大源、華為雲等。更改系統鏡像源的操作這裡不作細講,我們以 apt
和 pacman
為例,簡要介紹軟體安裝、卸載和搜索等操作。
# 更新資料庫
sudo apt update
sudo pacman -Sy
# 以更新軟體包的方式更新系統
sudo apt upgrade
sudo pacman -Su
# 安裝 vim
sudo apt install vim
sudo pacman -S vim
# 卸載 libreoffice
sudo apt remove libreoffice*
sudo pacman -R libreoffice*
編輯器之神:VIM
Linux 終端若無法承擔文字編輯任務,便擔不得強大之名。事實上,若論終端文字編輯工具,nano
、vim
、Emacs
均為此類,但 nano
側重簡單易用,而 vim
和 Emacs
則擁有著強大的功能。較之 Emacs
提供了豐富的組合鍵,vim
則更傾向於使用單鍵執行操作。若您更喜歡 Emacs
的優雅,請暫且移步 Emacs
教程;若您與我同樣選擇 vim
,歡迎繼續閱讀。
在終端下啟動
vim
# 啟動 vim [並打開文件 xxx.sh] vim [xxx.sh]
vim
各種模式啟動
vim
後,預設進入的是NORMAL
模式,即普通模式(有時也稱命令模式),在此模式下可以移動輸入游標,執行單鍵命令,並可鍵入:
激活底部命令模式。在此模式下,h
/j
/k
/l
分別表示左/下/上/右。當按下i
/a
(I
/A
) 時,將從當前游標所在字元之前/後(行首/行尾)進入INSERT
模式,即插入模式。若按下v
/V
/Ctrl
+v
時進入VISUAL
/VISUAL LINE
/VISUAL BLOCK
模式,即視圖模式。在普通模式下,還可以按x
/d
執行刪除、按y
執行複製、按gg
/G
/^
/$
跳轉至開頭/結尾/行首/行尾、按u
/Ctrl
+r
執行撤銷/重做操作。在
INSERT
模式下能夠執行字元輸入操作,完成輸入後按Esc
結束。在VISUAL
模式下可以移動游標進行文本選取,併進一步執行d
/y
等完成刪除/複製等操作。在任何模式下,您都可以按Esc
返回到普通模式,並請記住,vim
區分大小寫,因此時刻註意您的鍵盤狀態!
在使用vim
編輯文檔和代碼時,請註意在普通模式和插入模式之間靈活切換,以將輸入操作碎片化,從而能夠更靈活地執行撤銷與重做操作,因為vim
將每次從進入插入模式開始,到按Esc
回到普通模式的一整個過程認為是一次插入操作。當編輯完成後,可以鍵入:wq
或:x
來保存文件並退出vim
。如果要丟棄修改,不保存而直接退出,可以鍵入:q!
。vim
查找與替換在普通模式下,按下鍵盤上的
/
鍵即進入查找模式,此時在底部會顯示鍵入信息,支持正則表達式,按下Enter
完成鍵入並跳轉到查找到的高亮結果。如需暫時關閉高亮,請在底部命令模式下執行nohl
命令。vim
的替換命令更加強大。其基本格式為:[range]s/from/to/[flags]
,其中冒號表示進入底部命令模式,range
表示範圍(行),from
表示查找目標,可以是正則表達式,to
表示替換成的字元串,flag
表示選項:g
-替換所有 /c
-替換前確認 /e
-忽略錯誤。例:# 將每一行的所有 `Flag` 替換為 `flag` :%s/Flag/flag/g # 將第6行的第一個 `int` 替換為 `double` :6s/int/double/ # 將從第8行到倒數第5行的所有數字替換為 `num` :8,$-4s/[0-9]\+/num/g # 將游標所在行的下一行的所有單詞刪除 :.+1s/[a-z|A-Z]\+//g
vim
多文件編輯多視窗模式:在終端中鍵入
vim -o2 [xxx.cpp [yyy.cpp]]
可將視圖水平分割成上下兩個視窗,若參數使用大寫字母O
則為豎直分割。此外,在vim
的普通模式下,鍵入:split
可水平分割為上下兩個視窗查看當前文件,或鍵入:vsplit
豎直分割。當然,若split
命令有參數,則嘗試打開文件。在多視窗狀態下,按下組合鍵Ctrl
+w
激活視窗操作,此時可按h
/j
/k
/l
切換視窗,並可按r
/R
/x
/X
交換視窗位置。多標簽模式:在終端中鍵入
vim -p2 [xxx.cpp [yyy.cpp]]
可激活vim
的多標簽頁模式,或在vim
中執行:tabe [file.txt]
建立新的標簽頁(併在新標簽頁中打開文件file.txt
)。在此狀態下,鍵入gt
/gT
可順序/逆序遍歷標簽頁。vimrc
資源文件與
shell
類似,vim
在啟動時會載入一個資源文件,並分析執行資源文件中預定義的所有命令。這一般包括vim
的個性化設置如視圖佈局和主題等,還會有一些vim
插件的配置數據,有時我們也會在其中編寫一些按鍵映射和函數定義,用以執行一些自動化操作,特別是編譯和運行程式。要配置一個適合於自己的vimrc
文件,請移步相關教程和文檔,這裡不作贅述。
使用 Linux 溜起 C/C++
眾所周知,C語言程式調試分兩步走:碼代碼、跑程式,當然,這是因為中間一系列步驟都被各大 IDE 簡化了。即使現在,手裡握著 Linux 的我們依舊可以選擇使用 IDE,並且我們也確實有許多優秀的候選項。不過這篇文章並非介紹這些 IDEs for Linux,作為開箱即用的軟體套件,它們幾乎不需要被介紹。即使您還是希望選擇一個 IDE,最好也瞭解一下背後的過程。
簡單來說,C語言從代碼到目標程式的構建過程分為預處理、編譯、彙編、鏈接四步,在沒有 IDE 幫助的情形下,我們就需要手動完成這些操作。幸運的是,編譯器通常允許我們忽略中間的具體步驟,直接從輸入源代碼到輸出目標程式。自然,我們也可以選擇輸出中間文件,這在很多情況下往往十分必要。假如我們現在已經擁有一個使用 vim
或其他任何編輯器編寫的源代碼文件 hello.c
,我們可以在 shell
中使用 GCC 工具(GNU Compiler Collection)完成編譯操作:
# 若無 GCC 套件,先安裝
sudo apt install gcc
sudo pacman -S gcc
# 將 hello.c 編譯成目標程式(`-o` 選項可指定輸出文件名)
gcc hello.c [-o hello.out]
# 執行編譯輸出的可執行文件(參數)
./a.out [argument list]
# 只進行到彙編,輸出 obj 文件
gcc -c hello.c [-o hello.o]
# 只進行到編譯,輸出彙編代碼文件
gcc -S hello.c [-o hello.s]
# 只作預處理,從標準輸出展示結果(可重定向到文件)
gcc -E hello.c [> hello.txt]
# 編譯過程中產生調試信息
gcc -g hello.c
# 顯示所有警告信息
gcc -Wall hello.c
# 優化級別 [0-4]
gcc -O2 hello.c
# 更多用法請參考 `man gcc`
在進行大型項目、多文件的軟體開發過程中,逐個編譯源文件是非常不明智的,這時候可以考慮採用
makefile
自動化編譯過程,通過分析文件之間的依賴關係,確保所有文件保持最新,同時又不執行冗餘的操作。比如當某一個或多個文件更改時,不必重新處理所有源代碼,而只需要重新編譯修改的文件和引用它的文件。如您正有相關需求,請移步makefile
相關文檔。
到這裡,我們已經完成了將源代碼構建為目標程式的過程,如果編譯時加入了調試信息,那麼現在可以使用 gdb
進行調試工作——儘管這也許會相當麻煩。我們可以通過 gdb -h
和 man gdb
命令來獲取它的參數和命令以及其他介紹,這裡給出一個示例。
# 啟動 gdb (並打開目標程式)
gdb [a.out]
gdb
相關命令:
(gdb) file a.out
載入可執行文件
(gdb) list
列出源代碼
(gdb) break 6
在第六行添加斷點
(gdb) run hello world argu3 argu4
運行待調試程式並給出參數列表
(gdb) print str
輸出當前變數 str 的值
(gdb) next
執行下一條語句,不進入函數
(gdb) step
執行下一條語句,進入函數內部
(gdb) display i
監視變數 i
(gdb) continue
繼續運行,直到下一個斷點
(gdb) delete 1
刪除編號為1的斷點
(gdb) delete display 1
刪除編號為1的監視點
(gdb) kill
終止程式執行
(gdb) quit
退出調試器
暫停筆於此,如有謬誤,歡迎指正!