%%
# 纲要
> 主干纲要、Hint/线索/路标
# Q&A
#### 已明确
#### 待明确
> 当下仍存有的疑惑
**❓<font color="#c0504d"> 有什么问题?</font>**
# Buffer
## 闪念
> sudden idea
## 候选资料
> Read it later
%%
# Linux 软件包管理系统
Linux 的软件包管理系统使用**数据库**记录以下信息,控制软件和库的安装:
- Linux 系统中**已安装的软件**
- 每个已安装的**软件包的版本**
- 每个软件包**安装了哪些文件**
软件包存储在**仓库服务器(repository)** 上,可以利用本地 Linux 系统中的软件包管理器通过 Internet 访问,在其中搜索新的软件包,或是更新系统中已安装的软件包。
软件包之间通常存在依赖关系,被依赖的包必须提前安装,而**软件包管理器会自动检测依赖关系并优先安装好所依赖的软件包**。
# 不同 Linux 发行版中的软件包管理系统
不同 Linux 发行版采用的**软件包管理系统** 各不相同,各自内置的命令也不相同。
Linux 发行版中广泛使用的两种主要的包管理器是 `dpkg` 和 `rpm`。
| 发行版 distribution | 包管理器 | 软件包格式 | 命令 | 相关工具 |
| -------------------------- | ---- | --------- | ------ | ---------------- |
| Debian/**Ubuntu**等 | dpkg | **deb 包** | `dpkg` | `apt`(`apt-get`) |
| RedHat/**CentOS**/Fedora 等 | rpm | **rpm 包** | `rpm` | `yum`(=>`dnf`) |
^s00psd
> [!NOTE]
> - `dpkg` 与 `rpm` 命令用于安装**已下载到本地机器上的 deb 包 / rmb 包**;
> - `apt` 与 `yum` 命令是从包管理器中设置的仓库服务器中直接在线拉取、下载软件包并安装到本地
> (下载软件包到本地后,**安装时底层仍然是通过 dpkg 或 rpm 进行安装**)
>
<br><br>
# dpkg 包管理器
## dpkg 工具
`dpkg` 用以安装、更新、删除 `deb`包文件(**用于本地系统上的软件包**,不会在线下载),也支持 `tar`包。
```shell
dpkg <package> # 安装该软件包
dpkg -l # 查看所有已安装的软件包
dpkg -L <package> # 查看与该软件包相关的所有文件
dpkg --search <absolute_fine_name> # 查找该文件属于哪个软件包
```
##### dpkg 中断报错解决方法

<br><br>
## APT 工具
**APT 工具集**从 Linux 发行版**仓库**服务器上**在线下载**并安装软件包。
**APT (advanced package tool)** 工具集包含命令如下:
- `apt-cache`
- `apt-get`
- `apt`:**对上面两个命令的封装**
`apt`命令基本格式: `apt [option] command`
> [!Info] `apt` 命令概览:
>
> 
>
>
>
```shell
# 查看软件包
apt list # 显示仓库中所有可用的软件包
apt --installed list # 显示已安装在系统中的软件包
# 显示某个软件包的详细信息
# 注: `apt show`命令显示的是从仓库获取的包的信息, 不会指明该包是否已安装
apt show <package>
# 查找软件包
# search将显示"名称"或"描述"中包含搜索关键字的所有软件包
apt search <package>
apt --names-only search <package> # 查找软件包:只按名字搜索
# 安装软件包
apt install <package>
# 查看可升级的软件包
apt list --upgradable # 查看所有可升级的软件信息
apt list --upgradable -a # 查看所有可升级的软件的全部版本信息
# 检查已安装软件包是否有可用的更新(不会安装,只给报告)
# 该命令会访问仓库, 获取最新的软件版本信息后, 将可更新的软件列表并保存在本地。
apt update
# 升级软件包
apt upgrade # 升级所有已安装的软件包. 升级为仓库中可用的最新版本
apt full-upgrade
# 卸载软件包
apt remove <package> # 删除软件包, 但保留数据和配置文件
apt purge <package> # 删除软件包及其所有数据和配置文件
apt autoremove # 删除所有被标记为原本存在依赖关系, 但不再被需要的包.
```
<br>
### apt 的仓库服务器
apt 默认的**软件仓库服务器地址**保存在文件 `/etc/apt/sources.list` 中,apt 在搜索 & 安装 & 更新时都**只会从该文件里指定的仓库中**拉取安装包。
该文件中有 **`deb` 和 `deb-src` 两种形式**指定的仓库源:
- `deb` 表明这是一个**已编译程序**的仓库源。
- `deb-src` 表明这是一个源代码的仓库源。
文件中**每行指定一个源**,格式为:`deb (or deb-src) address distribution_name package_type_list `
> [!NOTE]
> Linux 发行版开发人员努力确保加入仓库的软件包版本不会彼此之间发生冲突。 **因此通过仓库升级或安装软件包**通常是最安全的方法。
>
> [!example] `/etc/apt/sources.list` 文件内容示例
> ![[_attachment/02-开发笔记/11-Linux/Linux 软件管理.assets/IMG-Linux 软件管理-C6A69B00ECDF7FD377AE51FDB2BC1905.png|466]]
<br>
### 设置 APT 源
将 apt 默认源**更换为国内源**即是需要修改`/etc/apt/sources.list` 文件[^1]。
更新后**执行 `sudo apt update` 命令**,获取软件更新信息。
### apt 的默认安装路径
| | 路径 |
| -------------- | ------------------------------------ |
| 下载的软件包的缓存位置 | `/var/cache/apt/archives` |
| 安装后软件所在的目录 | `/usr/share` 或 `/usr/local `或 `/opt` |
| 软件的可执行文件所在目录 | `/usr/bin` |
| 配置文件位置 | `/etc` |
| lib 文件位置(预编译库) | `/usr/lib` |
| 头文件路径 | `/usr/include` |
> [!example]
>
> 如下,安装的 git,可执行文件在`/usr/bin/git`, 而软件的位置在`/usr/share/man/man1/git.1.gz`
>
> 
>
>
> [!info] apt 与 dpkg 的关联
>
> **apt 底层通过 `dpkg` 来安装所下载的软件包**,所有已安装包都登记在 **dpkg 的数据库 `/var/lib/dpkg/status`** 里。
> 因此,通过 `dpkg -l` 可查看系统中 **==所有已安装的 Debian 包==及其版本号**。
>
> 示例:
>
> ```shell
> # 安装C++的 fmt 库
> sudo apt install libfmt-dev
>
> # 查看已安装的fmt库的版本号
> dpkg -l | grep libfmt
> ```
>
> ![[_attachment/02-开发笔记/11-Linux/Linux 软件管理.assets/IMG-Linux 软件管理-770EC5731BC71B9D50DBBB94DD3AFC96.png|510]]
>
<br><br><br>
# rmp 包管理器
### yum 工具
略
### dnf 工具
dnf 是 yum 的升级版,包含一些新增特性。
```shell
dnf list installed # 查看系统中所有已安装的软件包
dnf list <package> # 显示软件包的详细信息
dnf list installed <package> # 显示软件包的详细信息, 并检查是否已安装
dnf provides <file_name> # 查找该文件属于哪个软件包
dnf install <package> # 安装软件包
dnf list upgrades # 查看已安装软件包的所有可用更新
dnf upgrade <package> # 更新指定软件; 未指定时更新"所有软件"
dnf upgrade-minimal <package> # 将软件包升级至最新的bug修复版或安全补丁版, 而非最新的最高版
dnf remove <package> # 卸载软件包
# 处理依赖关系损坏(broken dependency)
dnf clean all
dnf upgrade <package>
# 若仍无法解决, 则用以下命令查看软件包的所有依赖关系.
dnf repoquery --deplist <package>
# 查看当前的仓库源
dnf repolist
```
#### dnf 的仓库服务器
dnf 默认的软件仓库服务器地址保存在:
- 配置文件 `/etc/dnf/dnf.conf`
- 或 `/etc/yum.repos.d` 目录中的单独文件
<br><br>
%%
# 使用容器管理软件
> 对应用程序开发人员而言,要想发行一款能够安装在所有 Linux 发行版中的程序,就必须创建多个发行版本,以适应不同的软件包管理器,还需要考虑其程序所依赖的哪些库文件在大多数 Linux 发行版中可用,以及库文件的版本。
>
> 为此,十分繁琐、耗时耗力。
云计算带来了**应用程序打包方式**的一种新范式:**应用程序容器**(application container)。
应用程序容器创建了一个**环境**,其中包含了应用程序**运行所需的全部文件**,包括运行时库文件。开发人员随后可以将应用程序容器作为单个软件包分发,保证能够在任何 Linux 系统中正常运行。
snap、flatpak

```shell
snap version
```
### Snap 容器
Ubuntu 发行版内置 **snap 应用程序容器**(Ubuntu 16.04LTS 引入)。
snap 打包系统会将应用程序所需的所有文件集中到单个 snap 分发文件中。
snap 应用程序运行在后台,可通过 snap 命令行工具查询 snap 数据库。
```shell
snap version # 检查snap是否正在运行
snap list # 查看当前已安装的snap应用程序列表
snap find <program> # 在snap仓库中搜索指定程序
snap info <program> # 查看snap应用程序的详细信息
sudo snap install <program> # 安装新的snap应用程序
sudo snap remvoe <program> # 删除某个snap应用程序
sudo snap disable <program> # 停用某个snap应用程序
sudo snap enable <program> # 重新启用某个snap应用程序
```
### flatpak 容器
flatpak 容器是一个独立的开源项目,与 Linux 发行版没有直接关联。
Ret Hat、CentOS 以及 Fedora 都倾向于使用 flatpak,而不是 Ubuntu 中的 snap。
### snap 和 Docker 的区别
%%
# 参考资料
# Footnotes
[^1]: [Ubuntu apt更换国内源-CSDN博客](https://blog.csdn.net/da_kao_la/article/details/85488682)