Linux軟硬鏈接和動靜態(tài)庫詳解
一、如何理解目錄
所以我們說Linux下一切皆文件,那么目錄是文件嗎?
是的,因為它也有自己的inode,我們可以通過ls -i
的命令來查看我們目錄對應(yīng)的inode
目錄的內(nèi)容就是該目錄下文件的文件名和對應(yīng)文件的inode映射關(guān)系,這樣我們就可以在目錄中打開文件
每個目錄創(chuàng)建出來都會有兩個隱藏文件一個是.一個是..,它們的本質(zhì)是什么,它們作為一個文件的屬性和內(nèi)容是什么,通過下面的學(xué)習(xí)我們會知道
二、軟鏈接
我們先來通過ln -s
給我們的test目錄上個軟鏈接
我們發(fā)現(xiàn)這個軟鏈接是有自己的inode的,我們前面說過,操作系統(tǒng)只認inode而不是文件名,所以它也是一個獨立的文件,其實它的數(shù)據(jù)塊里保存的是指向的文件的路徑,軟鏈接就相當(dāng)于我們電腦上的快捷方式,我們對軟鏈接進行操作,發(fā)現(xiàn)原文件會發(fā)生變化
當(dāng)我們的原來的文件刪除后,如下圖
我們發(fā)現(xiàn)變紅了,失效了,說明軟鏈接對原文件是有依賴性的,源文件被刪除軟鏈接就會失效
三、硬鏈接
通過命令ln
建立硬鏈接
我們可以看到,硬連接的inode與原文件的inode是相同的,我們在前面提到過,這里第三列的2是硬鏈接數(shù),現(xiàn)在我們可以很清楚地解釋了,硬鏈接數(shù)就是多個文件同時使用一個inode的數(shù)字,有多少文件硬鏈接數(shù)就是多少
我們修改file文件,對應(yīng)的硬連接也會發(fā)生修改,因為它們就是一個文件
當(dāng)我們將file文件刪除,我們會發(fā)現(xiàn),硬鏈接數(shù)變成了1,并且我們就算打開硬鏈接其中的數(shù)據(jù)也不會消失,這更加證明了操作系統(tǒng)只認inode不認文件名,因為inode結(jié)構(gòu)體中,有一個引用計數(shù)的計數(shù)器,它就是硬鏈接數(shù),同一inode下,只要引用計數(shù)數(shù)大于0,那么這個文件的所有硬鏈接以及這個文件都共用這個inode,共用一塊空間
但是我們的操作系統(tǒng)是不允許我們自己對目錄建立硬鏈接,原因有四:
- 1.避免文件系統(tǒng)循環(huán)引用:如果允許對目錄創(chuàng)建硬鏈接,可能會形成目錄的循環(huán)引用,例如,目錄 A 通過硬鏈接指向目錄 B,而目錄 B 又通過硬鏈接指向目錄 A,這樣就會形成一個無限循環(huán),當(dāng)文件系統(tǒng)進行某些操作,如遞歸遍歷目錄樹時,就會陷入死循環(huán),導(dǎo)致系統(tǒng)資源被無限消耗,最終可能使系統(tǒng)崩潰
- 2.保證文件系統(tǒng)的一致性:目錄在文件系統(tǒng)中起著組織和管理文件的重要作用,其結(jié)構(gòu)的穩(wěn)定性對于文件系統(tǒng)的正常運行至關(guān)重要,硬鏈接的特性使得多個文件名可以指向同一個 inode,如果對目錄創(chuàng)建硬鏈接,可能會破壞目錄結(jié)構(gòu)的清晰性和一致性,例如,一個文件可能會出現(xiàn)在多個不同的目錄層次中,這會讓用戶和系統(tǒng)難以確定文件的真實位置和歸屬,增加文件管理的復(fù)雜性
- 3.簡化文件系統(tǒng)的實現(xiàn)和管理:文件系統(tǒng)通過 inode 和鏈接計數(shù)來管理文件和目錄,對于文件的硬鏈接,鏈接計數(shù)可以準確地反映有多少個文件名指向同一個 inode,但對于目錄來說,如果允許創(chuàng)建硬鏈接,鏈接計數(shù)的管理會變得非常復(fù)雜。因為目錄的結(jié)構(gòu)和內(nèi)容不僅與自身的 inode 相關(guān),還與父目錄和子目錄的關(guān)系有關(guān),增加目錄的硬鏈接會破壞這種簡單的管理機制,使得文件系統(tǒng)的實現(xiàn)和維護變得更加困難
- 4.安全性:目錄的權(quán)限和訪問控制是基于其層次結(jié)構(gòu)進行管理的,如果允許對目錄創(chuàng)建硬鏈接,會使權(quán)限和訪問控制的管理變得復(fù)雜,例如,一個用戶可能通過硬鏈接繞過原本的權(quán)限設(shè)置訪問到其他目錄下的文件,從而破壞了文件系統(tǒng)的安全性
四、目錄中的.和. .
1、.
還記得我們的.的作用是什么嗎,就是定位當(dāng)前目錄,有了它我們才可以進行./相對路徑的定位,通過圖片我們可以發(fā)現(xiàn),test的inode和test中.的inode是一樣的,這是一個硬鏈接,一個當(dāng)前目錄的硬鏈接,操作系統(tǒng)雖然不讓用戶創(chuàng)建硬鏈接,但是為了方便我們使用相對路徑進行定位,它給我們默認創(chuàng)建這個硬鏈接,并且,這是一個隱藏文件,在搜索的時候默認是不會理會的
2、. .
我們來看一下…的inode,與2_9的.的inode相同,所以…這個就是上級文件2_9的硬鏈接,所以這樣的一切就解釋通了,當(dāng)我們在test目錄下執(zhí)行cd ..
指令的時候,其實就是執(zhí)行了cd 2_9
五、靜態(tài)庫
1、生成靜態(tài)庫
由兩個.o文件打包生成一個靜態(tài)庫,其中一個是打印功能,一個是加減乘除法的功能
首先定義一個lib變量mylib.a,表示要生成的靜態(tài)庫文件名lib=mylib.a
,然后寫出生成靜態(tài)庫生成所需要依賴的目標文件$(lib):cal.o print.o
寫出它們的依賴方法ar -rc $@ $^
,這個命令用于將所有的依賴文件$^
打包成靜態(tài)庫$@
,然后通過c文件生成目標文件對應(yīng)的依賴文件,最后的output是一個發(fā)布規(guī)則, 目標的作用是把編譯好的靜態(tài)庫文件和對應(yīng)的頭文件整理到特定的目錄結(jié)構(gòu)中,這在庫的發(fā)布、分發(fā)以及管理方面有著重要意義
這里的靜態(tài)庫.a文件實際上就是多個.o文件打包而已
然后make
一下生成靜態(tài)庫,make output
將庫發(fā)布,然后我們把生成的靜態(tài)庫lib復(fù)制到test文件夾中,進行測試,寫一個測試文件
2、靜態(tài)庫的使用
我們發(fā)現(xiàn)它報錯了,沒有找到cal.h頭文件,我們以前就知道,C語言包含頭文件有兩種形式,一種是<>,另一種就是" “,<>表示到系統(tǒng)指定的目錄下尋找頭文件,” "指的是在同級目錄下尋找頭文件,但是我們的頭文件不在我們的同級目錄下,而是在我們的同級目錄lib的下級目錄下,就需要以其他方式來尋找頭文件,一種方法是,把代碼中的路徑補全,另一種方法是,將頭文件拷貝到系統(tǒng)指定目錄中,一般為/usr/local/include/
或/usr/local/lib
,還有一種方法是,gcc編譯的時候加上-I
選項,指定編譯器搜索頭文件的路徑
這樣我們就把頭文件問題解決了,但是我們還是沒辦法進行編譯,因為它們無法進行鏈接,這是由于gcc的默認搜索路徑為動態(tài)庫lib64/libc.so
和靜態(tài)庫lib64/libc.a
,所以我們要進行指定搜索路徑
這里的gcc main.c -I ./lib/include -L ./lib/mylib/ -lmylib
生成可執(zhí)行程序有三個選項
-I
是指定頭文件搜索路徑-L
是指定庫文件搜索路徑路徑,如果-l
是指定庫路徑下要鏈接的庫名
另一種方式就是安裝庫,把頭文件.h復(fù)制到指定目錄usr/include
和庫文件.a復(fù)制到指定目錄lib64
中,還有一種方式就是建立軟鏈接,不過軟鏈接類似于上面路徑補全的方式#include <mysoftlink/cal.h>
大概這個樣子,因為我們軟鏈接的內(nèi)容就是指向位置的路徑
我們把靜態(tài)庫刪掉看看,程序是不是還能跑
六、動態(tài)庫
1、動態(tài)庫生成
我們拿同樣的程序進行動態(tài)庫的生成
這里在生成.o文件是要使用gcc的-fPIC
選項,這個選項的作用是產(chǎn)生與位置無關(guān)碼,主要是為了讓生成的代碼不依賴于特定的內(nèi)存地址,從而使動態(tài)庫可以被加載到任意的內(nèi)存地址并正確運行
生成.so文件時的-shared
選項就是要生成動態(tài)庫文件,因為動態(tài)庫也叫共享庫
2、動態(tài)庫使用
我們把動態(tài)庫放到test文件夾中,創(chuàng)建一個main.c測試文件,在make的時候又遇到了找不到頭文件的錯誤
我們按照使用靜態(tài)庫的方法使用動態(tài)庫,發(fā)現(xiàn)雖然生成了可執(zhí)行文件,但是連接不到動態(tài)庫
我們使用ldd a.out
指令查看可執(zhí)行文件a.out連接的庫,發(fā)現(xiàn)動態(tài)庫這里是not found的
使用file a.out
可以看到dynamically linked(uses shared libs)a.out連接的就是動態(tài)庫
所以我們也有方法去解決這些問題
1、拷貝到系統(tǒng)默認的庫路徑usr/lib64
或lib64
(最常用,因為我們使用的庫多數(shù)都是成熟庫)
2、在系統(tǒng)默認的庫路徑usr/lib64
或lib64
下建立軟鏈接
3、將自己的庫所在的路徑,添加到系統(tǒng)的環(huán)境變量LD_LIBRARY_PATH中
4、在etc/ld.so.conf.d
建立自己的動態(tài)庫路徑的配置文件,然后使用命令ldconfig更新一下配置即可
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
記一次Centos服務(wù)器被掛馬的抓馬經(jīng)歷
這篇文章主要介紹了記一次Centos服務(wù)器被掛馬的抓馬經(jīng)歷分享,非常不錯,具有參考借鑒價值,需要的朋友參考下2017-01-01Ubuntu 16.04無法切換root權(quán)限問題的解決
root權(quán)限相信對大家來說都不陌生,下面這篇文章主要給大家介紹了關(guān)于Ubuntu 16.04無法切換root權(quán)限問題的解決方法,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-04-04谷歌云Google Cloud 啟用Ubuntu的SSH服務(wù)
默認情況下,當(dāng) Ubuntu 最初被安裝的時候,通過 SSH 進行遠程訪問是不被允許的,在 Ubuntu 上啟用 SSH 非常的簡單直接,需要的朋友可以參考下2023-12-12Linux刪文件力度過大導(dǎo)致IO占用太高的解決方案
這篇文章主要介紹了Linux刪文件力度過大導(dǎo)致IO占用太高的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04