Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù)詳解
一、如何理解目錄
所以我們說(shuō)Linux下一切皆文件,那么目錄是文件嗎?
是的,因?yàn)樗灿凶约旱膇node,我們可以通過(guò)ls -i的命令來(lái)查看我們目錄對(duì)應(yīng)的inode

目錄的內(nèi)容就是該目錄下文件的文件名和對(duì)應(yīng)文件的inode映射關(guān)系,這樣我們就可以在目錄中打開(kāi)文件
每個(gè)目錄創(chuàng)建出來(lái)都會(huì)有兩個(gè)隱藏文件一個(gè)是.一個(gè)是..,它們的本質(zhì)是什么,它們作為一個(gè)文件的屬性和內(nèi)容是什么,通過(guò)下面的學(xué)習(xí)我們會(huì)知道

二、軟鏈接
我們先來(lái)通過(guò)ln -s給我們的test目錄上個(gè)軟鏈接


我們發(fā)現(xiàn)這個(gè)軟鏈接是有自己的inode的,我們前面說(shuō)過(guò),操作系統(tǒng)只認(rèn)inode而不是文件名,所以它也是一個(gè)獨(dú)立的文件,其實(shí)它的數(shù)據(jù)塊里保存的是指向的文件的路徑,軟鏈接就相當(dāng)于我們電腦上的快捷方式,我們對(duì)軟鏈接進(jìn)行操作,發(fā)現(xiàn)原文件會(huì)發(fā)生變化
當(dāng)我們的原來(lái)的文件刪除后,如下圖

我們發(fā)現(xiàn)變紅了,失效了,說(shuō)明軟鏈接對(duì)原文件是有依賴性的,源文件被刪除軟鏈接就會(huì)失效
三、硬鏈接
通過(guò)命令ln建立硬鏈接

我們可以看到,硬連接的inode與原文件的inode是相同的,我們?cè)谇懊嫣岬竭^(guò),這里第三列的2是硬鏈接數(shù),現(xiàn)在我們可以很清楚地解釋了,硬鏈接數(shù)就是多個(gè)文件同時(shí)使用一個(gè)inode的數(shù)字,有多少文件硬鏈接數(shù)就是多少
我們修改file文件,對(duì)應(yīng)的硬連接也會(huì)發(fā)生修改,因?yàn)樗鼈兙褪且粋€(gè)文件


當(dāng)我們將file文件刪除,我們會(huì)發(fā)現(xiàn),硬鏈接數(shù)變成了1,并且我們就算打開(kāi)硬鏈接其中的數(shù)據(jù)也不會(huì)消失,這更加證明了操作系統(tǒng)只認(rèn)inode不認(rèn)文件名,因?yàn)閕node結(jié)構(gòu)體中,有一個(gè)引用計(jì)數(shù)的計(jì)數(shù)器,它就是硬鏈接數(shù),同一inode下,只要引用計(jì)數(shù)數(shù)大于0,那么這個(gè)文件的所有硬鏈接以及這個(gè)文件都共用這個(gè)inode,共用一塊空間


但是我們的操作系統(tǒng)是不允許我們自己對(duì)目錄建立硬鏈接,原因有四:
- 1.避免文件系統(tǒng)循環(huán)引用:如果允許對(duì)目錄創(chuàng)建硬鏈接,可能會(huì)形成目錄的循環(huán)引用,例如,目錄 A 通過(guò)硬鏈接指向目錄 B,而目錄 B 又通過(guò)硬鏈接指向目錄 A,這樣就會(huì)形成一個(gè)無(wú)限循環(huán),當(dāng)文件系統(tǒng)進(jìn)行某些操作,如遞歸遍歷目錄樹(shù)時(shí),就會(huì)陷入死循環(huán),導(dǎo)致系統(tǒng)資源被無(wú)限消耗,最終可能使系統(tǒng)崩潰
- 2.保證文件系統(tǒng)的一致性:目錄在文件系統(tǒng)中起著組織和管理文件的重要作用,其結(jié)構(gòu)的穩(wěn)定性對(duì)于文件系統(tǒng)的正常運(yùn)行至關(guān)重要,硬鏈接的特性使得多個(gè)文件名可以指向同一個(gè) inode,如果對(duì)目錄創(chuàng)建硬鏈接,可能會(huì)破壞目錄結(jié)構(gòu)的清晰性和一致性,例如,一個(gè)文件可能會(huì)出現(xiàn)在多個(gè)不同的目錄層次中,這會(huì)讓用戶和系統(tǒng)難以確定文件的真實(shí)位置和歸屬,增加文件管理的復(fù)雜性
- 3.簡(jiǎn)化文件系統(tǒng)的實(shí)現(xiàn)和管理:文件系統(tǒng)通過(guò) inode 和鏈接計(jì)數(shù)來(lái)管理文件和目錄,對(duì)于文件的硬鏈接,鏈接計(jì)數(shù)可以準(zhǔn)確地反映有多少個(gè)文件名指向同一個(gè) inode,但對(duì)于目錄來(lái)說(shuō),如果允許創(chuàng)建硬鏈接,鏈接計(jì)數(shù)的管理會(huì)變得非常復(fù)雜。因?yàn)槟夸浀慕Y(jié)構(gòu)和內(nèi)容不僅與自身的 inode 相關(guān),還與父目錄和子目錄的關(guān)系有關(guān),增加目錄的硬鏈接會(huì)破壞這種簡(jiǎn)單的管理機(jī)制,使得文件系統(tǒng)的實(shí)現(xiàn)和維護(hù)變得更加困難
- 4.安全性:目錄的權(quán)限和訪問(wèn)控制是基于其層次結(jié)構(gòu)進(jìn)行管理的,如果允許對(duì)目錄創(chuàng)建硬鏈接,會(huì)使權(quán)限和訪問(wèn)控制的管理變得復(fù)雜,例如,一個(gè)用戶可能通過(guò)硬鏈接繞過(guò)原本的權(quán)限設(shè)置訪問(wèn)到其他目錄下的文件,從而破壞了文件系統(tǒng)的安全性
四、目錄中的.和. .
1、.

還記得我們的.的作用是什么嗎,就是定位當(dāng)前目錄,有了它我們才可以進(jìn)行./相對(duì)路徑的定位,通過(guò)圖片我們可以發(fā)現(xiàn),test的inode和test中.的inode是一樣的,這是一個(gè)硬鏈接,一個(gè)當(dāng)前目錄的硬鏈接,操作系統(tǒng)雖然不讓用戶創(chuàng)建硬鏈接,但是為了方便我們使用相對(duì)路徑進(jìn)行定位,它給我們默認(rèn)創(chuàng)建這個(gè)硬鏈接,并且,這是一個(gè)隱藏文件,在搜索的時(shí)候默認(rèn)是不會(huì)理會(huì)的
2、. .

我們來(lái)看一下…的inode,與2_9的.的inode相同,所以…這個(gè)就是上級(jí)文件2_9的硬鏈接,所以這樣的一切就解釋通了,當(dāng)我們?cè)趖est目錄下執(zhí)行cd ..指令的時(shí)候,其實(shí)就是執(zhí)行了cd 2_9
五、靜態(tài)庫(kù)
1、生成靜態(tài)庫(kù)
由兩個(gè).o文件打包生成一個(gè)靜態(tài)庫(kù),其中一個(gè)是打印功能,一個(gè)是加減乘除法的功能




首先定義一個(gè)lib變量mylib.a,表示要生成的靜態(tài)庫(kù)文件名lib=mylib.a,然后寫出生成靜態(tài)庫(kù)生成所需要依賴的目標(biāo)文件$(lib):cal.o print.o寫出它們的依賴方法ar -rc $@ $^,這個(gè)命令用于將所有的依賴文件$^打包成靜態(tài)庫(kù)$@,然后通過(guò)c文件生成目標(biāo)文件對(duì)應(yīng)的依賴文件,最后的output是一個(gè)發(fā)布規(guī)則, 目標(biāo)的作用是把編譯好的靜態(tài)庫(kù)文件和對(duì)應(yīng)的頭文件整理到特定的目錄結(jié)構(gòu)中,這在庫(kù)的發(fā)布、分發(fā)以及管理方面有著重要意義

這里的靜態(tài)庫(kù).a文件實(shí)際上就是多個(gè).o文件打包而已

然后make一下生成靜態(tài)庫(kù),make output將庫(kù)發(fā)布,然后我們把生成的靜態(tài)庫(kù)lib復(fù)制到test文件夾中,進(jìn)行測(cè)試,寫一個(gè)測(cè)試文件
2、靜態(tài)庫(kù)的使用


我們發(fā)現(xiàn)它報(bào)錯(cuò)了,沒(méi)有找到cal.h頭文件,我們以前就知道,C語(yǔ)言包含頭文件有兩種形式,一種是<>,另一種就是" “,<>表示到系統(tǒng)指定的目錄下尋找頭文件,” "指的是在同級(jí)目錄下尋找頭文件,但是我們的頭文件不在我們的同級(jí)目錄下,而是在我們的同級(jí)目錄lib的下級(jí)目錄下,就需要以其他方式來(lái)尋找頭文件,一種方法是,把代碼中的路徑補(bǔ)全,另一種方法是,將頭文件拷貝到系統(tǒng)指定目錄中,一般為/usr/local/include/或/usr/local/lib,還有一種方法是,gcc編譯的時(shí)候加上-I選項(xiàng),指定編譯器搜索頭文件的路徑


這樣我們就把頭文件問(wèn)題解決了,但是我們還是沒(méi)辦法進(jìn)行編譯,因?yàn)樗鼈儫o(wú)法進(jìn)行鏈接,這是由于gcc的默認(rèn)搜索路徑為動(dòng)態(tài)庫(kù)lib64/libc.so和靜態(tài)庫(kù)lib64/libc.a,所以我們要進(jìn)行指定搜索路徑

這里的gcc main.c -I ./lib/include -L ./lib/mylib/ -lmylib生成可執(zhí)行程序有三個(gè)選項(xiàng)
-I是指定頭文件搜索路徑-L是指定庫(kù)文件搜索路徑路徑,如果-l是指定庫(kù)路徑下要鏈接的庫(kù)名
另一種方式就是安裝庫(kù),把頭文件.h復(fù)制到指定目錄usr/include和庫(kù)文件.a復(fù)制到指定目錄lib64中,還有一種方式就是建立軟鏈接,不過(guò)軟鏈接類似于上面路徑補(bǔ)全的方式#include <mysoftlink/cal.h>大概這個(gè)樣子,因?yàn)槲覀冘涙溄拥膬?nèi)容就是指向位置的路徑
我們把靜態(tài)庫(kù)刪掉看看,程序是不是還能跑
六、動(dòng)態(tài)庫(kù)
1、動(dòng)態(tài)庫(kù)生成
我們拿同樣的程序進(jìn)行動(dòng)態(tài)庫(kù)的生成

這里在生成.o文件是要使用gcc的-fPIC選項(xiàng),這個(gè)選項(xiàng)的作用是產(chǎn)生與位置無(wú)關(guān)碼,主要是為了讓生成的代碼不依賴于特定的內(nèi)存地址,從而使動(dòng)態(tài)庫(kù)可以被加載到任意的內(nèi)存地址并正確運(yùn)行
生成.so文件時(shí)的-shared選項(xiàng)就是要生成動(dòng)態(tài)庫(kù)文件,因?yàn)閯?dòng)態(tài)庫(kù)也叫共享庫(kù)
2、動(dòng)態(tài)庫(kù)使用
我們把動(dòng)態(tài)庫(kù)放到test文件夾中,創(chuàng)建一個(gè)main.c測(cè)試文件,在make的時(shí)候又遇到了找不到頭文件的錯(cuò)誤

我們按照使用靜態(tài)庫(kù)的方法使用動(dòng)態(tài)庫(kù),發(fā)現(xiàn)雖然生成了可執(zhí)行文件,但是連接不到動(dòng)態(tài)庫(kù)

我們使用ldd a.out指令查看可執(zhí)行文件a.out連接的庫(kù),發(fā)現(xiàn)動(dòng)態(tài)庫(kù)這里是not found的

使用file a.out可以看到dynamically linked(uses shared libs)a.out連接的就是動(dòng)態(tài)庫(kù)

所以我們也有方法去解決這些問(wèn)題
1、拷貝到系統(tǒng)默認(rèn)的庫(kù)路徑usr/lib64 或lib64(最常用,因?yàn)槲覀兪褂玫膸?kù)多數(shù)都是成熟庫(kù))
2、在系統(tǒng)默認(rèn)的庫(kù)路徑usr/lib64或lib64下建立軟鏈接
3、將自己的庫(kù)所在的路徑,添加到系統(tǒng)的環(huán)境變量LD_LIBRARY_PATH中
4、在etc/ld.so.conf.d 建立自己的動(dòng)態(tài)庫(kù)路徑的配置文件,然后使用命令ldconfig更新一下配置即可
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
記一次Centos服務(wù)器被掛馬的抓馬經(jīng)歷
這篇文章主要介紹了記一次Centos服務(wù)器被掛馬的抓馬經(jīng)歷分享,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下2017-01-01
Ubuntu 16.04無(wú)法切換root權(quán)限問(wèn)題的解決
root權(quán)限相信對(duì)大家來(lái)說(shuō)都不陌生,下面這篇文章主要給大家介紹了關(guān)于Ubuntu 16.04無(wú)法切換root權(quán)限問(wèn)題的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-04-04
Linux常見(jiàn)英文報(bào)錯(cuò)中文翻譯(菜鳥(niǎo)必知)
這篇文章主要介紹了Linux常見(jiàn)英文報(bào)錯(cuò)中文翻譯,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
谷歌云Google Cloud 啟用Ubuntu的SSH服務(wù)
默認(rèn)情況下,當(dāng) Ubuntu 最初被安裝的時(shí)候,通過(guò) SSH 進(jìn)行遠(yuǎn)程訪問(wèn)是不被允許的,在 Ubuntu 上啟用 SSH 非常的簡(jiǎn)單直接,需要的朋友可以參考下2023-12-12
Linux刪文件力度過(guò)大導(dǎo)致IO占用太高的解決方案
這篇文章主要介紹了Linux刪文件力度過(guò)大導(dǎo)致IO占用太高的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04
Linux驅(qū)動(dòng)之platform總線詳解
大家好,本篇文章主要講的是Linux驅(qū)動(dòng)之platform總線詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12
Linux 僵尸進(jìn)程產(chǎn)生原因及解決方法
這篇文章主要介紹了Linux 僵尸進(jìn)程產(chǎn)生原因及解決方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-02-02

