詳解在 Ubuntu 從外部存儲(chǔ)庫(kù)安裝軟件包
你大概知道怎么在 Ubuntu 中使用 ??apt?
? 命令安裝軟件包。那些軟件包都是來(lái)自 Ubuntu 的官方存儲(chǔ)庫(kù)。
那第三方或者外部存儲(chǔ)庫(kù)呢?不,我這里并不是要講 PPA。
早晚你會(huì)碰到那種至少四行的安裝說(shuō)明:你需要安裝名為 ??apt-transport-https?
? 的包、操作一下 GPG 和 源列表source list
沒(méi)有什么印象的話,那我分享一個(gè) ??在 Ubuntu 上安裝最新版本的 Yarn?? 的例子:
當(dāng)你需要直接從開(kāi)發(fā)者那里安裝編程工具的時(shí)候,大概率會(huì)碰到這種安裝方式。
許多人只是按照說(shuō)明進(jìn)行操作,并不會(huì)去思考其中的原理。這也沒(méi)什么不對(duì),但了解該過(guò)程實(shí)際上可以提升你在這方面的知識(shí),而且有助于之后排除故障。
我來(lái)解釋一下這些代碼背后的邏輯。
理解從外部存儲(chǔ)庫(kù)安裝的過(guò)程
在你繼續(xù)往下閱讀之前,我強(qiáng)烈建議你先看看下面這兩篇文章,方便理解后續(xù)的概念:
為了讓你有點(diǎn)印象,這里有一張軟件包存儲(chǔ)庫(kù)和 ??Linux 中的包管理器?? 的圖片。
Illustration of repository and package manager
整件事情其實(shí)就是在系統(tǒng)中添加一個(gè)新的外部存儲(chǔ)庫(kù)。這樣,你就可以從這個(gè)新存儲(chǔ)庫(kù)下載并安裝可用的軟件包。如果這個(gè)存儲(chǔ)庫(kù)提供了包版本的更新,你可以在更新系統(tǒng)的同時(shí)更新這些軟件包(??apt update && apt upgrade?
?)。
那么,這是什么工作原理呢?讓我們一條一條地過(guò)一遍。
第 1 部分:為 apt 獲取 HTTPS 支持
第一行是這樣的:
??curl?
? 是一個(gè) ??Linux 終端下載文件的工具??。這里主要的部分是安裝 ??apt-transport-https?
?,但事實(shí)上已經(jīng)不需要了。
明白了嗎?這個(gè) ??apt-transport-https?
? 包讓你的系統(tǒng)通過(guò) HTTPS 協(xié)議安全訪問(wèn)存儲(chǔ)庫(kù)。按照設(shè)計(jì),Ubuntu 的存儲(chǔ)庫(kù)使用 http 而不是 https 協(xié)議。
看看下面的截圖。 https 這張圖是我已經(jīng)添加到系統(tǒng)中的外部存儲(chǔ)庫(kù)。Ubuntu 的存儲(chǔ)庫(kù)和 PPA 使用 http 協(xié)議。
在舊版本的 ??apt?
? 包管理器中,不支持 https 協(xié)議。??apt-transport-https?
? 包為 ??apt?
? 添加了 https 支持。要新增一個(gè)使用 https 的存儲(chǔ)庫(kù),首先就得先安裝此包。
我之前不是說(shuō)不需要安裝這個(gè)包了嗎?是的,因?yàn)檩^新版本的 ??apt?
?(高于 1.5)已經(jīng)支持 https,所以你不需要再安裝 ??apt-transport-https?
?。
但是你依然看到我在說(shuō)明中提到了這個(gè)包。這更多是出于遺留原因,而且可能還有很舊的發(fā)行版在使用舊版本的 ??apt?
? 包。
現(xiàn)在,你可能想知道既然 https 是安全協(xié)議,那為什么 Ubuntu 的存儲(chǔ)庫(kù)還要使用 http 而不是 https。這難道沒(méi)有安全風(fēng)險(xiǎn)嗎?接著往下看你就知道答案了。
第 2 部分:添加遠(yuǎn)程存儲(chǔ)庫(kù)的 GPG 密鑰
Linux 存儲(chǔ)庫(kù)內(nèi)置了基于 GPG 密鑰的安全機(jī)制。每個(gè)存儲(chǔ)庫(kù)都將其 GPG 公鑰添加到你的系統(tǒng)信任密鑰中。來(lái)自存儲(chǔ)庫(kù)的包由這個(gè) GPG 密鑰“簽名signed”,并且通過(guò)這份存儲(chǔ)的公鑰,系統(tǒng)能夠驗(yàn)證軟件包正是來(lái)自這個(gè)存儲(chǔ)庫(kù)。
如果 ??密鑰之間不匹配,你的系統(tǒng)會(huì)發(fā)出提醒??,而不會(huì)繼續(xù)從該存儲(chǔ)庫(kù)安裝或者更新軟件包。
到目前為止,一切都很順利。下一步是將外部存儲(chǔ)庫(kù)的 GPG 公鑰添加到你的 Linux 系統(tǒng),以便它能接收來(lái)自該存儲(chǔ)庫(kù)的軟件包。
在上面的命令中,你使用 ??curl?
? 從指定的 URL 下載 GPG 密鑰。選項(xiàng) ??-sS?
? 能夠讓你不看多余的輸出(靜默模式),但會(huì)顯示錯(cuò)誤(如果有的話)。最后一個(gè) ??-?
? 告訴 ??apt-key?
? 使用標(biāo)準(zhǔn)輸入stdin而不是文件(在本例中是 ??curl?
? 命令的輸出)。
??apt-key add?
? 命令已經(jīng)將下載的密鑰添加到系統(tǒng)中。
你可以通過(guò) ??apt-key list?
? 命令查看系統(tǒng)中各種存儲(chǔ)庫(kù)添加的 GPG 密鑰。
List GPG keys
這是將 GPG 密鑰添加到系統(tǒng)的一種方法。你會(huì)看到一些其它的命令,看起來(lái)略有不同,但效果一樣,都是將存儲(chǔ)庫(kù)的公鑰添加到你的系統(tǒng)里面。
你會(huì)注意到 ??apt-key?
? 已被棄用的警告。在 Ubuntu 22.04 之前,你還可以使用 ??apt-key?
? 命令,但它最終會(huì)被刪除?,F(xiàn)在不需要杞人憂天。
第 3 部分:將外部存儲(chǔ)庫(kù)添加到源列表
下個(gè)命令是在系統(tǒng)的源列表中添加一個(gè)新條目。這樣,你的系統(tǒng)就會(huì)知道它得檢查該存儲(chǔ)庫(kù)中的包和更新。
有一個(gè)文件 ??/etc/apt/sources.list?
? 包含 Ubuntu 存儲(chǔ)庫(kù)的詳細(xì)信息。最好不要隨便動(dòng)這個(gè)文件。所有新增的存儲(chǔ)庫(kù)都應(yīng)放在 ??/etc/apt/sources.list.d?
? 目錄中相應(yīng)的文件里(約定以 ??.list?
? 結(jié)尾)。
External repository should have their own sources list file in the /etc/apt/sources.list.d directory
這使得包管理變得更容易。如果你要從系統(tǒng)中刪除一個(gè)存儲(chǔ)庫(kù),只需刪除相應(yīng)的源文件即可。無(wú)需修改主 ??sources.list?
? 文件。
讓我們?cè)僮屑?xì)地看一下這行命令。
使用 ??sh?
? 可以在一個(gè)新的 shell 進(jìn)程中運(yùn)行命令,而不是 ??子 shell??。 ??-c?
? 選項(xiàng)告訴 ??sh?
? 命令從參數(shù)而不是標(biāo)準(zhǔn)輸入讀取命令。然后它運(yùn)行 ??echo?
? 命令,也就是把 ??deb https://dl.yarnpkg.com/debian/ stable main?
? 這一行添加到 ??/etc/apt/sources.list.d/yarn.list?
? 文件(會(huì)創(chuàng)建該文件)。
現(xiàn)在,你可以通過(guò)各種方法在指定目錄中創(chuàng)建 ??.list?
? 文件并在其中添加包含存儲(chǔ)庫(kù)詳細(xì)信息的數(shù)據(jù)行。你也可以像這樣使用:
明白了吧?
第 4 部分:從新添加的存儲(chǔ)庫(kù)安裝應(yīng)用程序
到目前為止,你已經(jīng)將存儲(chǔ)庫(kù)的 GPG 密鑰和存儲(chǔ)庫(kù)的 URL 添加到系統(tǒng)中。
但是系統(tǒng)仍然不曉得這個(gè)新存儲(chǔ)庫(kù)中有哪些可用的包。這就是為什么你需要先使用下面這個(gè)命令更新包元數(shù)據(jù)的本地緩存:
這時(shí)你的系統(tǒng)就已經(jīng)知道新增存儲(chǔ)庫(kù)中可用軟件包的信息,現(xiàn)在可以試試安裝軟件包:
為了節(jié)省時(shí)間,你可以在 ??同一行挨著運(yùn)行這兩個(gè)命令??e。
??&&?
? 可以確保第二個(gè)命令只會(huì)在前一個(gè)命令沒(méi)有任何報(bào)錯(cuò)的前提下運(yùn)行。
整個(gè)流程就是這樣。
有沒(méi)有豁然開(kāi)朗呢,還是一臉懵逼?
我已經(jīng)解釋了在 Ubuntu 中使用外部存儲(chǔ)庫(kù)背后的邏輯。希望你現(xiàn)在能更好地理解它,當(dāng)然可能還有很多細(xì)節(jié)會(huì)讓你困惑。
如果你還不清楚或者還有其他問(wèn)題,可以聯(lián)系我。