APT(Advanced Package Tool)从软件包仓库安装和更新软件。在 Debian 13(Trixie)上,软件源以两种格式定义:传统的一行式 .list 文件,以及较新的 deb822 格式的 .sources 文件。全新安装的 Trixie 默认使用 deb822 格式。

请注意:已配置的仓库不一定处于启用状态,已启用的仓库也不一定能正常工作。 本文介绍如何列出 Debian 系统上已启用的仓库、找到定义它们的源文件,并排查某个软件包背后没有可用仓库的情况。

大部分步骤也适用于 Ubuntu、Linux Mint 及其他基于 Debian 的发行版,但默认文件名不同。本文只涉及 APT 仓库,不包括 Flatpak remote、Snap channel 或容器镜像仓库。

最快方式:读取 APT 已加载的索引

在 Debian 13 及更早版本上,查看已启用的 APT 仓库可运行:

apt-get indextargets --format '$(REPO_URI) $(RELEASE) $(COMPONENT)' 'Created-By: Packages' | sort -u

不需要 root 权限。它按仓库、套件、组件输出已启用的条目,每行一个。

以下为 Debian 13 桌面版的示例输出:

https://deb.debian.org/debian/ trixie contrib
https://deb.debian.org/debian/ trixie main
https://deb.debian.org/debian/ trixie non-free
https://deb.debian.org/debian/ trixie non-free-firmware
https://deb.debian.org/debian/ trixie-updates main
https://dl.google.com/linux/chrome-stable/deb/ stable main
https://download.docker.com/linux/debian/ trixie stable
https://packages.microsoft.com/repos/edge-beta/ stable main
https://repo.protonvpn.com/debian/ stable main
https://security.debian.org/debian-security/ trixie-security main
https://security.debian.org/debian-security/ trixie-security non-free-firmware

该命令读取 APT 解析后的配置,因此对 .list 和 .sources 文件都有效。

需要 root 权限的命令只有 sudo apt update 和 sudo apt modernize-sources,其余命令可用普通用户运行。

用 apt-get indextargets 与 apt policy 核对

直接读文件只能看到“写了什么”;APT 命令能告诉你它“实际加载了什么”,并且对两种文件格式一视同仁。

apt-get indextargets 是列出已启用仓库最直接的方式:

apt-get indextargets --format '$(REPO_URI) $(RELEASE) $(COMPONENT)' 'Created-By: Packages' | sort -u

其中:

  • Created-By: Packages 将输出限制为二进制(deb)软件包索引;不加过滤时,输出还会包含 Contents 和 Translations 条目。
  • sort -u 去除仓库服务多种架构时产生的重复条目。
  • 要列出源码包(deb-src)仓库,把过滤条件改为 'Created-By: Sources'。

另一种方式是:

apt policy

不带软件包名运行时,它会打印 APT 当前使用的软件包来源及其优先级。这是 apt-cache policy 的现代形式,两者都能用。条目形如:

Package files:
100 /var/lib/dpkg/status
release a=now
.
.
.
500 https://security.debian.org/debian-security trixie-security/non-free-firmware amd64 Packages
release v=13,o=Debian,a=stable-security,n=trixie-security,l=Debian-Security,c=non-free-firmware,b=amd64
origin security.debian.org
500 https://security.debian.org/debian-security trixie-security/main amd64 Packages
release v=13,o=Debian,a=stable-security,n=trixie-security,l=Debian-Security,c=main,b=amd64
origin security.debian.org
500 https://deb.debian.org/debian trixie-updates/main amd64 Packages
release v=13-updates,o=Debian,a=stable-updates,n=trixie-updates,l=Debian,c=main,b=amd64
origin deb.debian.org
500 https://deb.debian.org/debian trixie/non-free-firmware amd64 Packages
release v=13.7,o=Debian,a=stable,n=trixie,l=Debian,c=non-free-firmware,b=amd64
origin deb.debian.org
500 https://deb.debian.org/debian trixie/non-free amd64 Packages
release v=13.7,o=Debian,a=stable,n=trixie,l=Debian,c=non-free,b=amd64
origin deb.debian.org
500 https://deb.debian.org/debian trixie/contrib amd64 Packages
release v=13.7,o=Debian,a=stable,n=trixie,l=Debian,c=contrib,b=amd64
origin deb.debian.org
500 https://deb.debian.org/debian trixie/main amd64 Packages
release v=13.7,o=Debian,a=stable,n=trixie,l=Debian,c=main,b=amd64
origin deb.debian.org
Pinned packages:

需要注意:apt policy 反映的是 APT 已经下载的软件包索引。如果刚刚启用或禁用某个源,需要先运行 sudo apt update,否则输出可能与配置不一致。apt-get indextargets 直接读取配置,没有这个限制。

注意: 这两个命令只能说明某个源处于启用状态,不能说明其服务器可访问或签名有效。下文“验证仓库是否可用”会说明这一点。

源文件在哪里,以及 deb822 迁移

APT 从以下位置读取仓库列表:

  • /etc/apt/sources.list
  • /etc/apt/sources.list.d/*.list
  • /etc/apt/sources.list.d/*.sources

sources.list.d 中扩展名不符的文件会被忽略。文件名含有字母、数字、下划线、连字符和句点之外字符的文件同样会被忽略。

全新安装的 Trixie 将主要 Debian 仓库放在 /etc/apt/sources.list.d/debian.sources;/etc/apt/sources.list 通常只含注释,或根本不存在。

如果从旧版本升级而来,可能仍保留传统 /etc/apt/sources.list。两种格式可以并存。

要将旧 .list 文件转换为 deb822,运行:

sudo apt modernize-sources

该命令会列出将要转换的文件,并在修改前请求确认。它会写入新的 .sources 文件并备份原文件,例如备份为 /etc/apt/sources.list.bak。

要只显示非注释行,可运行:

grep -HvE '^[[:space:]]*(#|$)' \
/etc/apt/sources.list \
/etc/apt/sources.list.d/*.list \
/etc/apt/sources.list.d/*.sources 2>/dev/null

这会打印所有非空且非注释的行,并附上文件名前缀。它展示的是“已配置”的内容,但无法判断 deb822 文件中哪些配置段处于“启用”状态,因为被禁用的配置段同样包含非注释行。请结合下文的启用规则,或使用前述 APT 命令判断。

判断条目是启用还是禁用

传统 .list 文件

有效条目以 deb 或 deb-src 开头;以 # 开头的行是禁用的。例如:

deb https://deb.debian.org/debian trixie main
# deb https://example.com/debian stable main

第一条启用,第二条未启用。条目可以带方括号选项,例如架构和签名密钥:

deb [arch=amd64 signed-by=/usr/share/keyrings/example.gpg] https://example.com/debian stable main

要只列出 .list 文件中的有效行,运行:

grep -hE '^[[:space:]]*deb(-src)?[[:space:]]' \
/etc/apt/sources.list /etc/apt/sources.list.d/*.list 2>/dev/null

注意这不会解析 .sources 文件,也不会检查仓库是否可用。

deb822 .sources 文件

deb822 文件使用命名字段,空行分隔配置段。典型配置段如下:

Types: deb deb-src
URIs: https://deb.debian.org/debian
Suites: trixie trixie-updates
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg

规则要点:

  • 配置段默认启用,只有当包含设为假值的 Enabled 字段(如 Enabled: no)时才禁用。字段名和值不区分大小写(即 case-insensitive),因此 enabled: No 同样会禁用配置段。
  • Types 可同时列出 deb 和 deb-src;只要出现 deb-src,源码仓库即为启用。
  • URIs、Suites 和 Components 都可以包含多个空格分隔的值,因此一个配置段可以定义多个仓库。
  • Signed-By 可以是密钥环文件路径,也可以是内联密钥块。
  • 一个文件可以包含多个配置段,每段独立启用或禁用。

要只打印 .sources 文件中启用的配置段,可运行:

for f in /etc/apt/sources.list.d/*.sources; do
[ -f "$f" ] || continue
printf '### %s\n' "$f"
awk -v RS= '
tolower($0) ~ /(^|\n)types:/ &&
tolower($0) !~ /(^|\n)enabled:[ \t]*(no|false|0)[ \t]*(\n|$)/ {
print $0 "\n"
}' "$f"
done

该过滤器打印每个含有 Types 字段且没有假值 Enabled 的配置段。它只是便于阅读的辅助手段,前述 APT 命令仍是更可靠的答案。

要查找被显式禁用的配置段,运行:

grep -n -i 'Enabled:' /etc/apt/sources.list.d/*.sources

需要查看结果周围的配置段,才能确定每条结果属于哪个仓库。

验证仓库是否可用

运行(需要 root):

sudo apt update

APT 会尝试从每个已启用的源刷新软件包索引。检查输出中的错误,例如:

  • 404 Not Found:仓库路径或套件可能不正确,或已不再提供。
  • NO_PUBKEY:APT 找不到验证该仓库所需的公钥。
  • The repository is not signed:APT 无法按要求验证仓库元数据。
  • 连接或 DNS 错误:APT 无法访问仓库服务器。

警告和提示信息也要读,不要只看错误。它们经常暴露配置问题:

  • Target Packages ... is configured multiple times:同一个仓库在多个文件中重复定义,应删除重复项。
  • Skipping acquire of configured file ... doesn't support architecture:该仓库不为你配置的某个架构提供软件包。
  • Ignoring file ... invalid filename extension:APT 因文件名问题跳过了 sources.list.d 中的某个文件。

更新干净完成只说明 APT 成功刷新了它处理的索引,并不保证某个特定软件包可用。

切勿通过禁用身份验证来“解决”签名错误。应检查仓库 URL,并按照仓库所有者的官方说明安装其签名密钥。

排查没有仓库的软件包

用 apt-cache policy 查看 APT 能安装的软件包版本及其来源:

apt-cache policy firefox-esr

如果列出的唯一来源如下所示,说明 APT 显示的是本地软件包数据库,而非某个仓库:

100 /var/lib/dpkg/status

这并不自动意味着仓库缺失或损坏,只说明 APT 在当前索引中没有该软件包的仓库版本。

常见原因包括:

  • 软件包从独立的 .deb 文件安装,从未添加过仓库。
  • 安装时软件包添加了自己的源文件,但该文件后来被删除、禁用或重命名。
  • 源条目存在但被注释掉、含有 Enabled: no,或指向已不存在的套件。
  • 该仓库上一次 apt update 失败,索引从未下载。
  • 软件包来自已被删除或禁用的仓库,例如在发行版升级过程中。

要找出当前没有任何仓库提供的所有已安装软件包,可运行:

apt list --installed 2>/dev/null | grep '\[installed,local\]'

标记为 local 的软件包在 APT 当前索引中没有仓库版本。

示例:Microsoft Edge Beta

假设已安装 Microsoft Edge Beta,但 apt-cache policy 只显示本地版本:

microsoft-edge-beta:
Installed: 145.0.3800.13-1
Candidate: 145.0.3800.13-1
Version table:
*** 145.0.3800.13-1 100
100 /var/lib/dpkg/status

Edge、Chrome 等厂商软件包通常从下载的 .deb 安装;其中许多会在安装过程中添加自己的 APT 源,但具体行为因厂商和版本而异。如果该源文件缺失或被禁用,就会出现上述输出。

第 1 步:查找现有源条目。

grep -RniE 'microsoft|edge' \
/etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null

仔细检查结果。文件名包含 edge 并不能证明其中有有效的 Edge 仓库。例如,文件可能只有下面这行被注释的内容:

#deb [arch=amd64] https://dl.google.com/linux/chrome/deb/ stable main

该条目处于禁用状态,而且指向 Google Chrome 而非 Microsoft Edge。

第 2 步:核对仓库和签名密钥。

如果不存在有效的 Edge Beta 条目,在添加前应查阅 Microsoft 当前的官方 Linux 安装说明,核实确切的仓库 URL、套件、架构和签名密钥安装方式。

如果现有条目引用了缺失的密钥环文件,应修正路径,或按官方说明安装密钥。不要猜测密钥文件名,也不要绕过签名验证。

第 3 步:刷新 APT 并复查。

sudo apt update
apt-cache policy microsoft-edge-beta

检查更新输出中的仓库和签名错误,然后确认是否列出了仓库版本。如果仍然只出现 /var/lib/dpkg/status,说明 APT 依然没有该软件包的仓库。

请注意:某个应用已安装,并不能证明它的仓库已启用或可用。 应核实源条目、刷新索引,并检查 policy 输出。

最后核对

在 Debian 13 上列出已启用的仓库,可从 apt-get indextargets 或 apt policy 入手。两者报告的都是 APT 实际从 .list 和 .sources 文件加载的内容,比手动读文件更可靠。用 /etc/apt/sources.list 和 /etc/apt/sources.list.d/ 中的文件找到每个软件源的出处,再按各自格式套用启用规则。

之后运行 sudo apt update,同时阅读错误和警告。如果某个软件包没有仓库版本,检查它的源文件、签名密钥,以及它是否从独立的 .deb 安装。如果还有旧的 .list 文件,可以考虑运行 sudo apt modernize-sources,让 APT 仓库列表统一为一种格式。