詳解在 Ubuntu 從外部存儲庫安裝軟件包

你大概知道怎么在 Ubuntu 中使用 ??apt?? 命令安裝軟件包。那些軟件包都是來自 Ubuntu 的官方存儲庫。
那第三方或者外部存儲庫呢?不,我這里并不是要講 PPA。
早晚你會碰到那種至少四行的安裝說明:你需要安裝名為 ??apt-transport-https?? 的包、操作一下 GPG 和 源列表source list
沒有什么印象的話,那我分享一個 ??在 Ubuntu 上安裝最新版本的 Yarn?? 的例子:
當你需要直接從開發者那里安裝編程工具的時候,大概率會碰到這種安裝方式。
許多人只是按照說明進行操作,并不會去思考其中的原理。這也沒什么不對,但了解該過程實際上可以提升你在這方面的知識,而且有助于之后排除故障。
我來解釋一下這些代碼背后的邏輯。
理解從外部存儲庫安裝的過程
在你繼續往下閱讀之前,我強烈建議你先看看下面這兩篇文章,方便理解后續的概念:
為了讓你有點印象,這里有一張軟件包存儲庫和 ??Linux 中的包管理器?? 的圖片。

Illustration of repository and package manager
整件事情其實就是在系統中添加一個新的外部存儲庫。這樣,你就可以從這個新存儲庫下載并安裝可用的軟件包。如果這個存儲庫提供了包版本的更新,你可以在更新系統的同時更新這些軟件包(??apt update && apt upgrade??)。
那么,這是什么工作原理呢?讓我們一條一條地過一遍。
第 1 部分:為 apt 獲取 HTTPS 支持
第一行是這樣的:
??curl?? 是一個 ??Linux 終端下載文件的工具??。這里主要的部分是安裝 ??apt-transport-https??,但事實上已經不需要了。
明白了嗎?這個 ??apt-transport-https?? 包讓你的系統通過 HTTPS 協議安全訪問存儲庫。按照設計,Ubuntu 的存儲庫使用 http 而不是 https 協議。
看看下面的截圖。 https 這張圖是我已經添加到系統中的外部存儲庫。Ubuntu 的存儲庫和 PPA 使用 http 協議。

在舊版本的 ??apt?? 包管理器中,不支持 https 協議。??apt-transport-https?? 包為 ??apt?? 添加了 https 支持。要新增一個使用 https 的存儲庫,首先就得先安裝此包。
我之前不是說不需要安裝這個包了嗎?是的,因為較新版本的 ??apt??(高于 1.5)已經支持 https,所以你不需要再安裝 ??apt-transport-https??。
但是你依然看到我在說明中提到了這個包。這更多是出于遺留原因,而且可能還有很舊的發行版在使用舊版本的 ??apt?? 包。
現在,你可能想知道既然 https 是安全協議,那為什么 Ubuntu 的存儲庫還要使用 http 而不是 https。這難道沒有安全風險嗎?接著往下看你就知道答案了。
第 2 部分:添加遠程存儲庫的 GPG 密鑰
Linux 存儲庫內置了基于 GPG 密鑰的安全機制。每個存儲庫都將其 GPG 公鑰添加到你的系統信任密鑰中。來自存儲庫的包由這個 GPG 密鑰“簽名signed”,并且通過這份存儲的公鑰,系統能夠驗證軟件包正是來自這個存儲庫。
如果 ??密鑰之間不匹配,你的系統會發出提醒??,而不會繼續從該存儲庫安裝或者更新軟件包。
到目前為止,一切都很順利。下一步是將外部存儲庫的 GPG 公鑰添加到你的 Linux 系統,以便它能接收來自該存儲庫的軟件包。
在上面的命令中,你使用 ??curl?? 從指定的 URL 下載 GPG 密鑰。選項 ??-sS?? 能夠讓你不看多余的輸出(靜默模式),但會顯示錯誤(如果有的話)。最后一個 ??-?? 告訴 ??apt-key?? 使用標準輸入stdin而不是文件(在本例中是 ??curl?? 命令的輸出)。
??apt-key add?? 命令已經將下載的密鑰添加到系統中。
你可以通過 ??apt-key list?? 命令查看系統中各種存儲庫添加的 GPG 密鑰。

List GPG keys
這是將 GPG 密鑰添加到系統的一種方法。你會看到一些其它的命令,看起來略有不同,但效果一樣,都是將存儲庫的公鑰添加到你的系統里面。
你會注意到 ??apt-key?? 已被棄用的警告。在 Ubuntu 22.04 之前,你還可以使用 ??apt-key?? 命令,但它最終會被刪除。現在不需要杞人憂天。
第 3 部分:將外部存儲庫添加到源列表
下個命令是在系統的源列表中添加一個新條目。這樣,你的系統就會知道它得檢查該存儲庫中的包和更新。
有一個文件 ??/etc/apt/sources.list?? 包含 Ubuntu 存儲庫的詳細信息。最好不要隨便動這個文件。所有新增的存儲庫都應放在 ??/etc/apt/sources.list.d?? 目錄中相應的文件里(約定以 ??.list?? 結尾)。

External repository should have their own sources list file in the /etc/apt/sources.list.d directory
這使得包管理變得更容易。如果你要從系統中刪除一個存儲庫,只需刪除相應的源文件即可。無需修改主 ??sources.list?? 文件。
讓我們再仔細地看一下這行命令。
使用 ??sh?? 可以在一個新的 shell 進程中運行命令,而不是 ??子 shell??。 ??-c?? 選項告訴 ??sh?? 命令從參數而不是標準輸入讀取命令。然后它運行 ??echo?? 命令,也就是把 ??deb https://dl.yarnpkg.com/debian/ stable main?? 這一行添加到 ??/etc/apt/sources.list.d/yarn.list?? 文件(會創建該文件)。
現在,你可以通過各種方法在指定目錄中創建 ??.list?? 文件并在其中添加包含存儲庫詳細信息的數據行。你也可以像這樣使用:
明白了吧?
第 4 部分:從新添加的存儲庫安裝應用程序
到目前為止,你已經將存儲庫的 GPG 密鑰和存儲庫的 URL 添加到系統中。
但是系統仍然不曉得這個新存儲庫中有哪些可用的包。這就是為什么你需要先使用下面這個命令更新包元數據的本地緩存:
這時你的系統就已經知道新增存儲庫中可用軟件包的信息,現在可以試試安裝軟件包:
為了節省時間,你可以在 ??同一行挨著運行這兩個命令??e。
??&&?? 可以確保第二個命令只會在前一個命令沒有任何報錯的前提下運行。
整個流程就是這樣。
有沒有豁然開朗呢,還是一臉懵逼?
我已經解釋了在 Ubuntu 中使用外部存儲庫背后的邏輯。希望你現在能更好地理解它,當然可能還有很多細節會讓你困惑。
如果你還不清楚或者還有其他問題,可以聯系我。
























