Linux apt 命令:在 Ubuntu/Debian 上管理软件包

apt(Advanced Package Tool 的缩写)是一个用于在 Ubuntu、Debian 及相关 Linux 发行版上安装、更新、删除以及管理 deb 软件包的命令行工具。它结合了 apt-getapt-cache 工具中最常用的命令,并对部分选项的默认值做了调整。

apt 是为交互式使用而设计的。在你的 shell 脚本中,建议优先使用 apt-getapt-cache,因为它们在不同版本之间保持向后兼容,并且拥有更多选项和功能。

大多数 apt 命令必须以具有 sudo 权限的用户身份运行。

本指南讲解日常包管理中最常用的 apt 命令。

更新软件包索引(apt update)

APT 软件包索引是一个数据库,记录了系统中已启用仓库所提供的可用软件包信息。

要更新软件包索引,运行下面的命令。它会从 APT 仓库拉取最新变更:

sudo apt update

安装软件包(apt install)

安装软件包非常简单,只需运行以下命令:

sudo apt install package_name

如果想用一条命令安装多个软件包,将它们以空格分隔列出即可:

sudo apt install package1 package2

要安装本地的 deb 文件,请提供该文件的完整路径。否则,命令会尝试从 APT 仓库获取并安装该软件包。

sudo apt install /full/path/file.deb

要安装某个软件包的特定版本,将版本号附加在软件包名之后。先运行 apt policy package_name 查看已启用仓库提供了哪些版本:

sudo apt install package_name=version

当同一个软件包在多个发行版中均可用时,你可以附加发行版名称来选择该版本。例如,下面的命令从 Debian backports 安装软件包,同时优先使用默认发行版的依赖:

sudo apt install package_name/trixie-backports

-t 选项(长格式为 --target-release)为整个事务设置一个目标发行版。这可能会从 backports 拉取额外的依赖,因此仅在你所选的软件包确实需要这些依赖时使用:

sudo apt install -t trixie-backports package_name

升级软件包(apt upgrade)

定期更新你的 Linux 系统是整体系统安全最重要的环节之一。

要将已安装的软件包升级到最新版本,运行:

sudo apt upgrade

该命令不会升级那些需要删除已安装软件包才能完成的软件包。

要在软件包尚未安装时仅升级它(而不是安装它),将 install--only-upgrade 一起使用:

sudo apt install --only-upgrade package_name

始终建议你配置自动安全更新。

完整升级(apt full-upgrade)

upgradefull-upgrade 的区别在于:后者在升级整个系统需要删除已安装软件包时,会执行删除操作。

sudo apt full-upgrade

跳过确认提示

在更改任何内容之前,apt 会显示它计划执行的操作,并等待你输入 Y-y 选项(长格式为 --yes)会提前回答该提示。当你已经了解并信任所提议的事务时使用它:

sudo apt install -y package_name

该选项同样适用于升级命令:

sudo apt upgrade -y
sudo apt full-upgrade -y

下面这条常见的单行命令会一步刷新软件包索引并升级所有内容:

sudo apt update && sudo apt upgrade -y

该行中的 -y 只作用于第二条命令。虽然 apt update 通常不进行提示,但当仓库版本信息发生变化时它可能要求确认,因此这条单行命令并不能保证无人值守运行。即使使用 install,在使用 -y 之前也要先审查所提议的更改,因为解决软件包冲突可能会删除已安装的软件包。对于脚本和 Dockerfile,应使用 apt-get 而非 apt,因为它的输出格式在各版本之间保持稳定。

重新安装软件包(apt install --reinstall)

如果一个软件包损坏,或者你想恢复它的文件,使用下面的命令重新安装:

sudo apt install --reinstall package_name

修复损坏的依赖

当安装过程被中断,或者使用 dpkg 安装软件包(它本身不会解析依赖)时,你可能会遇到软件包已被解包但未配置的状态。在这种状态下,apt 会拒绝继续,并提示你执行修复:

You might want to run 'apt --fix-broken install' to correct these.
The following packages have unmet dependencies:

不带软件包名运行该命令,即可安装缺失的部分并完成配置:

sudo apt install -f

-f 选项是 --fix-broken 的简写,因此 sudo apt --fix-broken install 作用相同。这也是用 dpkg -i 安装 deb 文件之后的标准后续步骤。

删除软件包(apt remove)

要删除一个已安装的软件包,输入以下命令:

sudo apt remove package_name

你也可以指定多个软件包,以空格分隔:

sudo apt remove package1 package2

remove 命令会卸载指定的软件包,但可能会保留一些配置文件。如果你想连同所有配置文件一起删除该软件包,请使用 purge 代替 remove

sudo apt purge package_name

删除未使用的软件包(apt autoremove)

每当系统上安装一个依赖其他软件包的新软件包时,这些依赖也会被一并安装。当该软件包被删除时,这些依赖会残留在系统中。这些残留的软件包不再被任何其他程序使用,可以安全删除。

要删除这些无用的依赖,使用以下命令:

sudo apt autoremove

要同时删除无用软件包及其配置文件,运行:

sudo apt autoremove --purge

列出软件包(apt list)

list 命令允许你列出可用、已安装和可升级的软件包。与 searchshowpolicy 一样,它只读取磁盘上已有的软件包数据,因此不需要 sudo

要列出所有可用的软件包,使用以下命令:

apt list

命令会打印所有软件包的列表,包含软件包的版本和架构信息。要查看某个特定软件包是否已安装,可以用 grep 命令过滤输出。

apt list | grep package_name

要只列出已安装的软件包,输入:

apt list --installed

在实际升级之前,获取可升级软件包的列表可能很有用:

apt list --upgradable

搜索软件包(apt search)

该命令允许你在可用软件包列表中搜索给定的软件包:

apt search package_name

如果找到,命令会返回名称匹配搜索词的软件包。

软件包信息(apt show)

在删除或安装新软件包之前,了解其依赖、安装大小、软件包来源等信息可能很有用。

要获取某个软件包的信息,使用 show 命令:

apt show package_name

软件包策略(apt policy)

使用 apt policy 查看将安装哪个版本,以及它来自哪个仓库:

apt policy package_name

在排查版本冲突或固定(pinned)软件包时,这很有帮助。

清理软件包缓存(apt clean / apt autoclean)

要删除缓存的软件包文件并释放磁盘空间,使用:

sudo apt clean

要只删除过期的缓存软件包,使用:

sudo apt autoclean

故障排查

E: Could not get lock /var/lib/dpkg/lock-frontend

另一个进程正在使用软件包系统,通常是 unattended-upgrades,或者另一个窗口中打开了包管理器。等待它完成后再重新运行命令。如果进程似乎卡住,用 sudo lsof /var/lib/dpkg/lock-frontend 找出它,优雅地终止它,然后运行 sudo dpkg --configure --pending 完成任何被中断的配置。切勿手动删除 dpkg 锁文件,那样可能损坏软件包数据库或文件系统。

sudo lsof /var/lib/dpkg/lock-frontend
sudo dpkg --configure --pending

E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)

该命令会更改系统,因此需要 root 权限,请在其前面加上 sudo。像 apt listapt search 这样的只读命令不需要。

E: Unable to locate package

要么是软件包索引已过期,要么是该软件包不在你已启用的仓库中。先运行 sudo apt update。如果仍然找不到,它可能位于你系统上未启用的仓库中,例如 Ubuntu 上的 universe,或者位于你需要自行添加的第三方仓库。

W: GPG error and NO_PUBKEY

你的某个仓库的签名密钥缺失或已过期,因此 apt 不会信任它的软件包列表。从仓库提供方下载当前密钥,将其保存在 /etc/apt/keyrings 下,并在仓库条目中通过 signed-by 选项指向该文件。

The following packages have been kept back

在 Ubuntu 上,这通常意味着更新正通过分阶段更新(phased updates)逐步发布。运行 apt policy package_name 并查找分阶段百分比。如果该软件包处于分阶段状态,请等待,APT 会在更新覆盖到你的系统时安装它。软件包也可能因依赖变化或被 hold 而保留。不要直接跳到 full-upgrade;仅当提议的解决方案确实要求删除时才使用它,并在确认前阅读删除列表。

快速参考

可打印的快速参考见 APT cheatsheet。

命令 说明
sudo apt update刷新软件包索引
sudo apt install <pkg>安装软件包
sudo apt install -y <pkg>安装且不显示确认提示
sudo apt install <pkg>=<version>安装特定版本
sudo apt install -f修复损坏的依赖
sudo apt upgrade升级所有已安装软件包
sudo apt full-upgrade升级,必要时删除软件包
sudo apt remove <pkg>删除软件包(保留配置文件)
sudo apt purge <pkg>删除软件包及其配置文件
sudo apt autoremove删除无用的依赖软件包
apt list --installed列出已安装的软件包
apt list --upgradable列出有待升级的软件包
apt search <pkg>搜索软件包
apt show <pkg>显示软件包详情
apt policy <pkg>显示可用版本及来源
sudo apt clean删除所有缓存的软件包文件
sudo apt autoclean删除过期的缓存软件包

常见问题

apt 代表什么?

APT 是 Advanced Package Tool 的缩写,是 Debian 及基于 Debian 的发行版所使用的包管理系统。apt 命令是你在终端中输入的那个前端,而 apt-getapt-cacheapt-mark 是隶属于同一系统的独立工具。

sudo apt 做什么?

sudo 以 root 权限运行其后的命令,而 apt 是包管理器。每个会更改系统的 apt 命令,例如 installremoveupgradeupdate,都需要这些权限,这就是为什么上面大多数示例都以 sudo 开头。

apt search、apt list 和 apt show 需要 sudo 吗?

不需要。这些命令只读取磁盘上已有的软件包数据,因此任何用户都可以运行。加上 sudo 不会改变它们返回的内容。

使用 apt install -y 安全吗?

当你清楚 APT 会做出哪些更改时是安全的。-y 选项会跳过正常的确认,即使只是安装一个具名软件包也可能删除存在冲突的软件包。在不确定的情况下,先不带 -y 运行命令,审查软件包列表后再确认,或将该选项添加到受控的自动化流程中。

apt update 与 apt upgrade 有什么区别?

apt update 刷新本地关于有哪些软件包及版本的记录,不安装任何东西。apt upgrade 安装刷新后的记录所揭示的更新版本。先运行 update,否则 upgrade 会基于过时的信息工作。

结论

对于日常包管理,先 sudo apt updatesudo apt upgrade 就能覆盖你大部分的需求。关于在脚本中何时使用 aptapt-get 的对比,参见 apt vs apt-get:两者有何区别。