Linux軟件包管理器–apt
Linux安裝軟件的方式
在Linux下安裝軟件的方法有以下三種:
- 下載到程序的源代碼,自己編譯出可執行程序
- 獲取deb安裝包、然后使用dpkg命令安裝。(不解決依賴關系)
- 通過apt進行安裝軟件。
小知識點: .rpm是Centos的安裝包;.deb是Ubuntu安裝包。
apt
apt是Linux中Ubuntu系統的一個前端軟件包管理器,能夠從指定的服務器中自動下載deb包并安裝,并可以自動處理依賴關系。
如下圖所示:
也就是說,apt就相當于是應用市場的名字,而我們通過應用市場下載軟件,會去服務器上拉取相應的安裝包下載到本地,然后在本地安裝。
而我們下載東西是需要聯網的,因此我們下載時需要聯網。
判斷是否聯網可以使用ping指令,如果不斷的進行打印,代表是在聯網狀態下的。
如下:
查找軟件包
我們可以使用apt list指令,這個指令可以列出apt中的全部包。
apt list
但這個指令一般都會直接刷屏,因此,我們一般都是搭配著管道和搜索使用。
如下:
apt list | grep lrzsz
但,這樣過于繁瑣,在apt中,我們可以直接使用search指令進行搜索。
apt search lrzsz
安裝軟件
安裝軟件,需要sudo權限。
指令: sudo apt install 軟件名
apt會自動找到需要下載的軟件包,然后詢問我們是否需要安裝,按“y”確認安裝,等到出現complete時,安裝成功。
現在,我們就可以安裝下lrzsz軟件。
apt install lrzsz
本地環境和云服務器之間文件的互傳
現在,我們說以下lrzsz的使用。
lrzsz可以完成云服務器和本地機器文件的互傳。
指令: rz -E
這個指令可以選擇從本地機器上傳到云服務器的文件
指令: sz 文件名
這個指令可以從云服務器發送文件到本地機器的指定文件夾。
軟件的卸載
卸載軟件使用的指令如下:
sudo apt remove 軟件名
vim
而我們在linux中編寫代碼的時候,肯定需要一個能夠寫代碼的工具。
那么,這個工具就是vim。
這里,我們介紹下vim。
vim的基本概念
vim作為一個多模式的文本編輯器,可以解決我們編寫代碼的問題。
我們主要學習vim的三個模式:
1、命令模式
在命令模式下我們可以:
- 控制屏幕光標的移動
- 字符、字、行的刪除,復制粘貼剪貼等操作。
2、插入模式
文字的輸入
3、底行模式
在底行模式下,我們可以保存文件,也可以進行一系列的操作,譬如查找字符串。
在底行模式下,還可以執行Linux的指令。
在vim中,模式不僅有三個,而是有很多個,我們還可以在底行模式下輸入vim help-mode查看當前vim的所有模式。
vim各模式的切換
首先,我們先學下怎么進入vim
vim 文件名
如果該文件存在,則使用vim進入,如果該文件不存在,則創建該文件并使用vim進入
進入vim時,默認是命令模式。
這時,我們按i,即可進入插入模式。
如果我們在插入模式中按Esc,即可再次進入到命令模式。
在命令模式中,按Shift+;,即可進入底行模式。
此時,我們如果想要回到命令模式,可以再按一次Esc。
命令模式指令
光標移動:
- h, j, k, l:這些是標準的光標移動命令,分別對應左、下、上、右移動一格。
- G:移動到文本的最后一行。
- $:移動到當前行的末尾。
- ^:移動到當前行的第一個非空字符位置。
- w:移動到下一個單詞的開頭。
- e:移動到下一個單詞的結尾。
- b:移動到上一個單詞的開頭。
- nl:跳轉到該行的指定位置(例如,5l表示跳到該行的第5個字符)。
- gg:移動到文檔的開頭。
- Shift+G:移動到文檔的末尾。
- Ctrl+b:向后滾動一屏。
- Ctrl+f:向前滾動一屏。
- Ctrl+u:向后滾動半屏。
- Ctrl+d:向前滾動半屏。
刪除: - x:刪除光標所在位置的字符。
- nx:刪除光標位置之后的指定個字符(例如,6x表示刪除6個字符)。
- X:刪除光標前一個字符。
- nX:刪除光標前面的指定個字符(例如,20X表示刪除光標前面的20個字符)。
- dd:刪除光標所在行。
- ndd:刪除光標所在行及其后的#行(例如,6dd表示刪除光標所在行及之后的6行)。
復制: - yw:將光標所在位置到單詞尾部的字符復制到緩沖區。
- nyw:復制#個單詞到緩沖區(例如,3yw表示復制接下來的3個單詞)。
- yy:復制光標所在行。
- nyy:復制從光標所在行往下的n行(例如,6yy表示復制從當前行開始的6行)。
- p:將緩沖區的內容粘貼到光標所在位置。
替換: - r:替換光標所在位置的字符。
- R:替換光標所在位置及其后的字符,直到按下 ESC 鍵。
撤銷與恢復: - u:撤銷上一個操作。可以多次按 u 來撤銷多次操作。
- Ctrl+r:恢復上一個撤銷的操作。
更改: - cw:更改光標所在位置到當前單詞的結尾。
- cnw:更改光標所在位置到下一個n個單詞的結尾(例如,c3w表示更改3個單詞)。
跳轉到指定行: - Ctrl+g:顯示光標所在行的行號。
- nG:跳轉到文檔中的第n行(例如,15G表示跳到第15行)。
底行模式指令(重要)
行號設置:
- set nu:顯示行號
- set nonu:取消行號
跳轉:
- n:n代表一個數字,在冒號后輸入一個數字,然后再按回車鍵即可跳轉到該行了。
查找字符:
- /關鍵字:先按/,再輸入想查找的字符,一直按n可以往后找到想要的字符。(從前向后)
- ?關鍵字:先按?,再輸入想查找的字符,一直按n可以往前找到想要的字符。(從后向前)
保存退出: - w:保存
- q:退出(如果沒有退出vim,則可以加一個!表示強制退出)
- wq:保存退出
分屏: - vs 文件名:多文件編輯
- Crtl+w+w:光標再多屏幕下進行切換
執行命令: - !+指令:在不退出vim的情況下,在指令前加上!就可以執行Linux的指令。
vim的配置方法
Vim 配置文件通常位于以下位置:
- 系統級配置文件:
/etc/vimrc
,適用于所有用戶。 - 用戶級配置文件:
~/.vimrc
,每個用戶可以自定義該文件。
詳細的vim配置,大家根據需求自己上網搜就好了哈
創建或編輯個人 .vimrc
- 切換到用戶的主目錄:
cd ~
.vimrc 文件(如果文件不存在,可以創建一個新的):
vim .vimrc
常用配置選項
在 .vimrc 中可以加入以下配置選項:
啟用語法高亮:
syntax on
啟用行號:
set nu
設置縮進為4
set shiftwidth=4
Liunx下C/C++編譯器:gcc/g++
gcc和g++分別是C和C++的編譯器。
gcc/g++的作用
C/C++程序在執行編譯時有以下四個步驟:
- 預處理(頭文件展開、去注釋、宏替換、條件編譯)
- 編譯(C代碼翻譯為匯編代碼)
- 匯編(匯編代碼轉化為二進制代碼)
- 鏈接(將各個二進制代碼進行鏈接)
下面,我們一邊講gcc,一邊寫這四個階段。
gcc/g++的語法
語法: gcc/g++ 選項 文件
常用選項:
- -E 只進行預處理
- -S 只進行預處理和編譯
- -c 進行預處理、編譯、匯編
- -o 將處理結果輸出到指定文件,后要跟文件名
- -static 對文件采用靜態鏈接的方式
- -g 生成調試信息(debug版本)(若不帶此選項,則默認生成release版本)
- -shared 盡量使用動態庫
- -w 不生成任何警告信息
- -O0/-O1/-O2/-O3 編譯器優化選項的四個級別,優化力度依次遞增。
預處理
gcc -E test.c -o test.i
- 預處理功能包含頭文件展開、去注釋、宏替換、條件編譯等。
- 預處理指令是以#開頭的代碼行
- -o選項是指目標文件,“.i”為結尾的文件為已經預處理過后的文件。
編譯
gcc -S test.i -o test.s
- 編譯階段中,gcc/g++會檢查代碼是否規范,是否具有語法錯誤,以及確定代碼的功能。在檢查無誤后,會將代碼翻譯為匯編語言。
- -o選項是指目標文件 “xxx.s”是翻譯后的原始程序。
匯編
gcc -c test.s -o test.o
-匯編階段是將-s文件轉化為-o文件,即目標文件。
-o文件是二進制目標代碼。
鏈接
gcc test.o -o test
- 鏈接的主要任務是將生成的各個.o文件進行鏈接,生成可執行文件。
- 若不帶-o選項,則默認生成的可執行文件名為a.out
- 不帶選項時,默認將預處理、編譯、匯編、鏈接四個過程全做完。
動靜態鏈接和動靜態庫
動靜態鏈接
靜態鏈接
在我們的實際開發中,不會將所有代碼放在?個源?件中,所以會出現多個源?件,?多個源?件之間不是獨?的,?會存在多種依賴關系,如?個源?件可能要調?另?個源?件中定義的函數,但,每個源?件又都是獨?編譯的,因此每個*.c?件會形成?個*.o?件,為了滿?前?說的依賴關系,則需要將這些源?件產?的?標?件進?鏈接,從?形成?個可以執?的程序。這個鏈接的過程就是靜態鏈接。
很顯然,靜態鏈接的弊端很明顯:
- 如果有多個程序都需要用到同一個函數,譬如printf;那么所有使用了printf的程序都需要有一份printf.o的副本。比較占空間。
- 更新?較困難:每當庫函數的代碼修改了,這個時候就需要重新進?編譯鏈接形成可執?程序。
但,靜態鏈接一般速度較快。
動態鏈接
動態鏈接的出現解決了靜態鏈接中提到問題。動態鏈接的基本思想是把程序按照模塊拆分成各個相對獨?部分,在程序運?時才將它們鏈接在?起形成?個完整的程序,?不是像靜態鏈接?樣把所有程序模塊都鏈接成?個單獨的可執??件。
動態鏈接的缺點是速度較慢,但是卻解決了靜態鏈接出現的問題。
動靜態庫
函數庫一般分為動態庫和靜態庫兩種:
- 靜態庫是指在編譯鏈接時,把庫文件的代碼全部都加載進入到可執行文件當中,因此生成的文件體積比較大,但是運行的時候也不需要庫文件了,靜態庫一般以.a為后綴。
- 動態庫與之相反,在編譯鏈接時沒有把庫文件的代碼加載到可執行文件當中,而是在程序運行時由鏈接文件加載庫,這樣可以節省系統的開銷,動態庫一般以.so為后綴。
Linux調試器—gdb/cgdb
gdb是不帶可視化界面的一種調試器,cgdb是帶可視化界面的調試器,鄙人更喜歡cgdb。
cgdb安裝指令如下:
sudo apt-get install -y cgdb
debug和release
首先,我們應該知道程序是有兩個版本的,分別是debug版本和release版本。
- debug:程序本身帶有調試信息,可以進行調試。
- release:程序本身不添加調試信息,無法進行調試。
在Linux當中gcc/g++默認生成的程序是release版本的,也就是說,是無法被調試的,如果想要生成的程序可以調試,需要加上-g選項。
如下:
gcc test.c -o test -g
這樣,生成的程序就是可以被調試的了。
gdb命令
- 進入gdb
gdb 文件名
- 調試
run/r:啟動調試
next/n:逐過程調試
step/s:逐語句調試
until 行號:跳轉
finish:執行完當前運行的函數后停止
continue/c:執行到下一個斷點處
set var 變量=x:修改變量的值
- 顯示
list/l n:顯示從第n行開始的源代碼,每次顯示10行。若n未給出則默認從上次的位置繼續往下查
list/l 函數名:顯示函數的源代碼
print/p 變量:打印變量的值
display 變量:將變量加入常顯示,即每次停止都打印一次
undisplay 編號:取消指定編號變量的常顯示
bt:查看各級函數調用以及參數
info/i locals:查看當前棧幀中局部變量的值
- 斷點
break/b n:在第幾行設置斷點
break/b 函數名:在函數體內的第一行設置斷點
info breakpoint/b:查看已設置的斷點信息
delete/d 編號:刪除指定編號的斷點
disable 編號: 禁用指定編號的斷點
enable 編號: 啟用指定編號的斷點
- 退出gdb
quit/q:退出gdb
Linux 項目自動化構建工具–make/Makefile
在 Linux 項目開發中,make 和 Makefile 作為自動化構建的核心工具,極大地提升了開發效率,尤其在處理大型復雜工程時,其優勢更為顯著。
make/Makefile 的作用
在大型工程里,源文件通常會依據類型、功能和模塊等維度,分散存儲在多個不同目錄中。Makefile 則通過精心定義一系列規則,精確指定了各個文件的編譯順序,從先編譯哪些文件到后編譯哪些文件,甚至對于更為復雜的操作流程,也能進行妥善處理。
使用 Makefile 的最大好處在于實現了“自動化編譯”。開發者只需提前編寫好 Makefile 文件,隨后僅需執行一次 make 命令,整個工程就能自動完成編譯過程。這種方式有效避免了手動編譯的繁瑣操作以及重復勞動,從而大幅提升了開發效率。(make命令只會執行第一個任務)
make 是一個命令行工具,專門用于解釋并執行 Makefile 中所定義的指令。可以說,make 是執行命令的工具,而 Makefile 則是存儲編譯規則的文件。能否熟練編寫 Makefile,在很大程度上反映了一個開發者是否具備處理大型工程的能力。
依賴關系和依賴方法
在使用 make 和 Makefile 之前,深入理解文件之間的依賴關系和依賴方法是至關重要的。
依賴關系
依賴關系描述了文件之間的依存關聯。具體而言,如果文件 A 的內容發生變更會對文件 B 產生影響,那么我們就稱文件 B 依賴于文件 A。
例如,在編譯過程中,test.o 文件是通過對 test.c 文件進行預處理、編譯、匯編等一系列操作后生成的。因此,我們可以明確地說 test.o 依賴于 test.c。
依賴方法
依賴方法指的是從一個文件(源文件)生成另一個文件(目標文件)所采用的具體工具或命令的操作過程。以 test.o 和 test.c 為例,test.o 依賴于 test.c,而通過執行 gcc -c test.c -o test.o
這條命令,就能夠實現從 test.c 生成 test.o 的過程,這一過程就是我們所說的依賴方法。
基本使用
代碼文件 (myproc.c)
#include <stdio.h>int main() {printf("hello, world!\n");return 0;
}
Makefile 文件
myproc: myproc.cgcc -o myproc myproc.c.PHONY: clean
clean:rm -f myproc
依賴關系與依賴方法及相關原理
依賴關系
在上述示例中,myproc
可執行文件依賴于 myproc.c
源文件。
依賴方法
編譯生成 myproc
的依賴方法是通過執行 gcc -o myproc myproc.c
這條命令來實現的。
為什么要寫 clean
在工程開發中,clean
任務的主要功能是清理編譯過程中生成的目標文件和中間文件。添加 clean
目標的原因如下:
- 工程構建完成后,為保持項目目錄整潔、節省磁盤空間,通常需清理生成的目標文件和中間文件。
clean
目標未被其他目標直接或間接依賴,其定義的命令不會自動執行。開發者需顯式執行make clean
來清理目標文件,以便重新編譯。- 為確保
clean
任務每次執行make clean
時都被執行,使用.PHONY
將其標記為偽目標。偽目標無論文件時間戳如何,相關命令都會執行。
總是被執行的含義
若未使用 .PHONY
標記,make
依據目標文件時間戳判斷是否執行任務。若文件時間戳顯示為最新,make
不重新執行任務。但 clean
任務不生成文件,我們希望每次都執行清理操作,不受時間戳影響。所以用 .PHONY
標記 clean
,保證每次執行 make clean
時都會執行清理。
make 原理
下面我們闡述下make原理:
1.查找 Makefile
make
會在當前目錄查找名為 Makefile
或 makefile
的文件。
2.解析第一個目標文件
若找到 Makefile
,make
會讀取第一個目標文件(target)。如上述例子,會找到 myproc
作為最終目標文件。
3.檢查文件是否需要更新
- 若
myproc
文件不存在,或其依賴文件(如myproc.o
)修改時間比myproc
新,make
會執行命令生成myproc
。 - 若
myproc
文件存在且時間戳最新,make
會跳過生成過程(.PHONY
標記的目標除外,會始終執行)。
4.遞歸生成依賴文件
若 myproc
依賴的 myproc.o
文件不存在,make
會在 Makefile
中查找生成規則并生成該文件。
- 最終生成目標文件
在依賴關系鏈最后,make
生成目標文件myproc
。若依賴文件存在且未修改,直接使用現有文件。
6.錯誤處理
- 查找依賴關系時,若某個依賴文件找不到,
make
會退出并報錯。 - 若命令定義有誤或編譯失敗,
make
會忽略錯誤,不再繼續執行。
7.依賴性判斷
make
主要關注文件依賴性。源文件和目標文件時間戳相同,make
認為目標文件是最新的,不執行任務;源文件較新時,make
重新執行命令。
.PHONY 偽目標
.PHONY 介紹
.PHONY
是 Makefile
文件中的關鍵字,用于聲明某個目標為偽目標。偽目標不對應實際文件,無論文件是否修改,相關命令每次都會執行。
如何使用 .PHONY
.PHONY: clean
clean:rm -rf myproc
在這個例子中,clean 是偽目標,用于清理生成的目標文件。即便沒有名為 clean 的文件,執行 make clean 時,刪除命令也會始終執行。
.PHONY 的作用
使用 .PHONY 可忽略文件時間戳判斷,強制每次執行任務。通常將 clean 任務定義為 .PHONY 偽目標,確保每次執行 make clean 時清除目標文件,為重新編譯做準備。
我們可以用stat看到如下:
$ stat XXX
File: ‘XXX’
Size: 987 Blocks: 8 IO Block: 4096 regular file
Device: fd01h/64769d Inode: 1321125 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ whb) Gid: ( 1000/ whb)
Access: 2024-10-25 17:05:30.430619002 +0800
Modify: 2024-10-25 17:05:25.940595116 +0800
Change: 2024-10-25 17:05:25.940595116 +0800
?件 = 內容 + 屬性
Modify: 內容變更,時間更新
Change:屬性變更,時間更新
Access:常指的是?件最近?次被訪問的時間。在Linux的早期版本中,每當?件被訪問時,其atime
都會更新。但這種機制會導致?量的IO操作。具體更新原則,不做過多解釋。
PHONY:讓make忽略源?件和可執??標?件的M時間對?