刚从 CentOS 切到 Ubuntu 那段时间,我在终端里最常干的一件蠢事,就是习惯性地敲yum install xxx。然后屏幕啪地弹出一行报错:There are no enabled repos. Run "yum repolist all" to see the repos you have...,后面还挂着老长一条让你去检查仓库列表的提示。第一次看到这行字的时候,我第一反应是“我是不是少配了 yum 源”,后来才发现,事情没那么简单——Ubuntu 系统本身根本不靠 yum 过日子,这报错背后藏着的是一整套包管理体系的差异。
这篇文章就围绕这个报错展开,把“Ubuntu 上为什么会有 yum”“这个报错到底在说什么”“到底该不该配 yum 源”这几个问题一次说透。我会给你三条可落地的出路:改用 apt、在受限场景下给 yum 配一个本地仓库、以及用容器把 yum 关进“笼子”里。每条方案都会给具体命令和坑点,适合从 Red Hat 系迁移到 Ubuntu 的运维、开发,也适合在 WSL 或虚拟机上折腾 Ubuntu 又被 yum 卡住的新手。
1. 先搞懂这个报错到底在说什么
1.1 字面意思逐字拆解
There are no enabled repos,翻译过来就是“当前没有处于启用状态的软件仓库”。yum repolist all这条命令的意思是让你列出系统里所有已知仓库,包括启用的和未启用的。如果你执行完yum repolist all,输出里只有一行提示,没有任何repo id列表,那基本可以断定:yum 本身是装上了,但 yum 的仓库配置文件一个都没生效。
yum 在执行任何 install、update、search 操作之前,会先去扫描/etc/yum.repos.d/目录下的所有.repo文件,然后过滤出里面enabled=1的仓库。只要满足条件的仓库数量为零,yum 就直接罢工,根本不会继续执行后面的操作。这是一个保护性机制,不是 bug。它怕你没有任何来源就去乱装东西,最后把系统搞成依赖黑洞。
1.2 为什么 Ubuntu 上会出现 yum 命令
这里有个关键认知需要先建立:Ubuntu 官方软件源里默认没有 yum,系统装完也不会自动生成/etc/yum.repos.d/目录。那为什么很多人会在 Ubuntu 上敲出 yum?我见过的情况大概有四种。
第一种,从 CentOS、Red Hat 或 Rocky Linux 迁移过来的老手,肌肉记忆太强,终端里下意识就敲 yum。这种情况系统压根没装 yum,你敲下去一般是command not found,而不是There are no enabled repos。
第二种,你会看到这个报错,说明系统里确实存在 yum 命令。那它哪来的?很可能是你或某个安装脚本从源码编译安装了 yum,或者通过某种方式把 RPM 系的工具链带进来了。
第三种,某些第三方教程为了在一个环境里同时兼容两种包管理习惯,教人强行安装 yum,结果仓库配置没跟上,运行时就报这个错。
第四种,容器或 WSL 环境里,基础镜像可能是 CentOS 或带 yum 的发行版,但用户以为自己在操作 Ubuntu,实际进去后发现仓库没启用。
无论哪种原因,核心矛盾就一句话:yum 是一个 RPM 系的包管理器,而 Ubuntu 是 Debian 系,它的默认包管理工具是 apt。这个矛盾不解决,光去配 yum 源治标不治本。
2. apt 和 yum 的本质差异:为什么在 Ubuntu 上硬用 yum 容易翻车
2.1 两套体系,从包格式到依赖算法完全不同
| 维度 | apt(dpkg) | yum/dnf(rpm) |
|---|---|---|
| 所属系列 | Debian / Ubuntu | Red Hat / CentOS / Rocky / Fedora |
| 包格式 | .deb | .rpm |
| 仓库文件 | /etc/apt/sources.list、/etc/apt/sources.list.d/ | /etc/yum.repos.d/*.repo |
| 仓库元数据 | Packages.gz / InRelease | repodata/repomd.xml |
| 依赖解析 | APT 解决 | rpm 依赖 + yum 解决 |
| 常用命令 | apt install、apt update | yum install、yum repolist |
这张表不是给你背的,而是让你理解:两套体系从底层就是不同的语言。Ubuntu 的系统库、内核头文件、glibc 等基础组件,全部是以 deb 包的形式安装和维护的。apt 在升级系统时会根据 deb 包之间的依赖关系统一处理,保证系统处于一致状态。
2.2 混用 yum 到底会出什么问题
如果在 Ubuntu 上强行用 yum 并且给它配了一个在线 RPM 仓库,你可能遇到的不是“能用”,而是“系统坏得莫名其妙”。
最典型的是依赖冲突。yum 解析依赖时,只看 RPM 包之间的依赖关系,它不知道当前系统里有大量 deb 包已经占用了某个库文件。比如某个 RPM 包要求libssl.so.1.1,yum 可能会尝试去装一个 RPM 版本的 openssl,把它覆盖到系统目录里。这时候 apt 这边完全不知情,下一次apt upgrade可能就会因为文件冲突直接中断,甚至把系统的 openssl 搞得版本错乱。
我自己见过一个真实案例:有人为了在 Ubuntu 上装某个只有 RPM 包的内网监控客户端,照着网上的教程硬配了 yum 源,结果装完发现系统里同时存在两套 zlib,然后 sshd 都起不来了。最后只能重装。
所以我的第一个建议非常明确:不要试图在实体 Ubuntu 系统上把 yum 当主力包管理器来用。yum 出现在 Ubuntu 上,本身就是个“异类”,这个报错其实是系统在保护你。
3. 先别急着配源,做个快速自查
3.1 确认 yum 的来历和仓库配置现状
遇到报错,第一件事不是满世界找源,而是先摸清现状。执行下面几条命令:
which yum yum --version ls -l /etc/yum.repos.d/ cat /etc/os-releasewhich yum能告诉你 yum 可执行文件在哪。ls -l /etc/yum.repos.d/用来确认仓库目录是否存在、里面有没有.repo文件。多数情况下你看到的会是目录不存在或者空目录,这就直接解释了报错原因。
cat /etc/os-release是确认一下你当前到底在什么系统里。因为我遇到过一些朋友在 WSL 里开了多个发行版,自己以为登的是 Ubuntu,实际进了 CentOS 容器。这种“身份认知”错误也会导致去 Ubuntu 的教程里找答案,越找越偏。
3.2 用一条决策树决定走哪条路
拿到自查结果后,我建议按下面这个逻辑做决策,不要拍脑袋:
- 只是想装 nginx、mysql、redis、python3 这类常规软件 → 直接放弃 yum,改用 apt,这是最省心的路。
- 某个软件官方只提供 rpm 包,而且你必须在 Ubuntu 上直接跑 → 先看有没有第三方维护的 deb 包或 PPA,没有的话再考虑 alien 转换或容器方案。
- 你的工作流就是围绕 RPM 系展开,yum 是刚需 → 不要跟 Ubuntu 硬扛,起一个 CentOS/Rocky 容器或虚拟机,在里面正常用 yum。
- 你就是出于学习目的,想看看 yum 的仓库机制是怎么运作的 → 可以在隔离环境里给 yum 配一个本地 repo,纯测试用。
记住这条逻辑:报错不是让你去补 yum 源,而是在提醒你重新思考工具选型。
4. 出路一:从源头改掉 yum 习惯,全面转向 apt
4.1 yum 到 apt 的命令换算表
如果决定留在 Ubuntu 生态里,最要紧的是把命令习惯切换过来。别小看这一步,很多人装软件失败就是因为在终端里不自觉地敲了 yum,然后去排查半天。
| 原来在 CentOS/RHEL 上的习惯 | Ubuntu 上等价操作 |
|---|---|
| yum install 包名 | sudo apt install 包名 |
| yum remove 包名 | sudo apt remove 包名 |
| yum update | sudo apt update && sudo apt upgrade |
| yum search 关键字 | apt search 关键字 |
| yum info 包名 | apt show 包名 |
| yum repolist | apt-cache policy 或查看 sources.list |
| yum clean all | sudo apt clean |
这里面最容易忽略的一步是apt update。CentOS 里yum install有时会自动刷新缓存,但 Ubuntu 的 apt 一般要求你先执行apt update同步软件源索引,再执行安装。如果你发现apt install提示找不到包,八成就是少了这一步。
4.2 Ubuntu 软件源配置与镜像加速
刚装完 Ubuntu 时,默认源指向的是官方服务器,国内访问速度可能不太理想。这个跟 yum 报错本身没关系,但很多人是在折腾源的路上越走越远。我建议在换源之前先备份原文件:
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak然后编辑/etc/apt/sources.list,把http://archive.ubuntu.com/ubuntu/替换成国内镜像源地址即可。不同的 Ubuntu 版本对应的代号不一样,20.04 是 focal,22.04 是 jammy,24.04 是 noble,替换时注意别搞混。
还有一点,新版 Ubuntu 的软件源可能分散在/etc/apt/sources.list.d/ubuntu.sources里,如果你打开sources.list发现文件是空的或者只有注释,去sources.list.d/目录看看。修改完统一执行:
sudo apt update看到Get:开头的一串输出,说明源已经能正常访问了。这时候再apt install,基本不会再卡壳。
4.3 某些软件只有 rpm 包,但你是 Ubuntu,怎么办
这是 yum 习惯之外最常见的痛点。比如某些商业软件、驱动或内网工具,官方只给了一个.rpm安装包。遇到这种情况,第一个思路是去官网看有没有Ubuntu或Debian版本;第二个思路是找有没有对应的 PPA 源,通过add-apt-repository添加第三方维护者的仓库;第三个思路才是用alien工具把 rpm 包转成 deb 包再安装。
alien的转换命令很简单:
sudo apt install alien sudo alien xxx.rpm sudo dpkg -i xxx.deb但我要提醒你,alien 只适合转换一些纯应用软件,不适合转换依赖系统库很深的东西。比如某些内联了内核模块或系统服务的包,转换后很可能跑不起来,甚至把系统的服务配置文件弄乱。遇到这种包,最稳妥的还是容器方案,我后面会细说。
5. 出路二:如果坚持要 yum,怎么给它配一个能用的仓库
5.1 先想清楚你要配哪种仓库
我知道有些人看这篇文章,就是想解决“yum 装好了但没有 enabled repo”的问题。那我给你一条明确的路径,但前提是:只建议在隔离、测试或内网环境中操作,不要在主力 Ubuntu 系统上拿它去访问通用 RPM 在线仓库然后做系统级更新。
yum 仓库一般分三类:在线仓库、本地目录仓库、离线镜像仓库。在 Ubuntu 上,最可控的是本地目录仓库。你可以把若干 rpm 包放到一个目录,用createrepo生成元数据,再写一个.repo文件让 yum 指向这里。这样 yum 就能正常运行,也能安装你放进去的 rpm 包。
5.2 本地 yum 仓库搭建实操
假设你想在 Ubuntu 上搭建一个本地 yum 仓库,并通过 yum 安装myapp.rpm,步骤如下。
第一步,准备目录和 rpm 包:
sudo mkdir -p /opt/rpm_packages sudo cp myapp.rpm /opt/rpm_packages/第二步,安装createrepo工具。Ubuntu 软件源里有createrepo或createrepo-c包,可以直接:
sudo apt install createrepo-c注意,这里用 apt 安装 createrepo 是为了给 yum 生成仓库元数据,属于“以子之矛攻子之盾”的操作,不受影响。
第三步,生成仓库元数据:
cd /opt/rpm_packages sudo createrepo .执行成功后,目录里会出现一个repodata子目录,里面有repomd.xml等文件。这是 yum 识别仓库的关键,没有这些文件,yum 会认为这个目录不是一个有效仓库。
第四步,写.repo配置文件:
sudo vi /etc/yum.repos.d/local.repo内容如下:
[local] name=Local RPM Repository baseurl=file:///opt/rpm_packages enabled=1 gpgcheck=0这里解释几个参数:
[local]是仓库 ID,必须唯一。name是仓库描述,可以随意。baseurl是仓库地址,本地目录用file://协议,后面跟绝对路径。enabled=1表示启用该仓库,不写默认也是启用,但建议显式写出来。gpgcheck=0表示跳过 GPG 签名校验。本地测试可以,生产环境不要这样做,风险后面说明。
第五步,验证并安装:
yum repolist all yum install myappyum repolist all此时应该能看到local仓库出现在列表里,状态为 enabled。如果还报There are no enabled repos,检查.repo文件的所有者和权限,yum 通常要求仓库文件对 root 可读,避免因权限问题被跳过。
5.3 这个方案里的三个坑
第一个坑是gpgcheck=0的风险。跳过 GPG 校验意味着 yum 不会验证 rpm 包的来源合法性。如果你只是往本地仓库里放自己拷贝的内网包,问题不大;但如果仓库地址被篡改,或者你从不明来源下载了 rpm 包,系统就失去了最后一道安全防线。有签名条件的,尽量保留gpgcheck=1并配置gpgkey。
第二个坑是$releasever变量。很多从网上抄来的.repo文件里都带$releasever这种变量,比如baseurl=https://mirrors.example.com/centos/$releasever/os/x86_64/。在 CentOS 上,yum 会自动从系统里读取版本号替换掉它;但在 Ubuntu 上,如果系统里没有对应的 RPM 发行版信息,这个变量可能被解析成空字符串,导致 repo 地址无效。我看到很多人的repolist all里出现“not enabled”或者行首有感叹号,就是变量没解析对。最简单的办法是写死版本号,或者用本地目录仓库避开在线地址。
第三个坑是 Ubuntu 下没有yum-config-manager。在 CentOS 里你可以用yum-config-manager --add-repo <url>快速添加仓库,但这个命令来自yum-utils包,而它是 RPM 系的工具。在 Ubuntu 上直接apt install yum-utils是装不到的,就算从源码编译,也会牵扯出一堆依赖问题。所以在 Ubuntu 上给 yum 配仓库,最可靠的方式永远是手动编写.repo文件。
6. 出路三:把 yum 关进容器,用对应的 Linux 发行版解决 RPM 需求
6.1 为什么容器方案才是最省心的“yum 环境”
如果你已经确定 yum 是刚需,又不想冒风险污染 Ubuntu 宿主机,我的建议非常直接:起一个 CentOS、Rocky Linux 或 AlmaLinux 容器,在容器里随便用 yum。这个方案的好处是隔离彻底,yum 在里面怎么折腾都不会影响宿主机;坏处是你需要安装 Docker 或 Podman 等容器运行时,多了一层学习成本。
但这层学习成本非常值得。因为绝大多数情况下,你需要 yum 只是为了安装一个 rpm 包,或者在一个 RPM 环境里运行某个构建任务,而不是真的想给 Ubuntu 系统换一套包管理。容器给了你一个“随用随走”的 RPM 环境。
第一步,安装 Docker(Ubuntu 上通常用 apt 即可):
sudo apt update sudo apt install docker.io sudo systemctl enable --now docker注意,Ubuntu 官方仓库里的 docker.io 可能不是最新版,但对大多数场景足够了。如果你的工作流对 Docker 版本有要求,再按 Docker 官方文档配置仓库安装,这里不展开。
第二步,拉取并进入一个 RPM 系镜像:
sudo docker run -it --rm rockylinux:9 bash进入容器后,你就是在一个标准的 Rocky Linux 9 环境里,yum(或 dnf)直接可用。先更新仓库缓存:
yum repolist yum install -y 需要安装的包这一步输出的repolist是容器自带的官方仓库,不会再出现There are no enabled repos。
6.2 容器里装好的软件怎么拿回宿主机
有人会问,我在容器里用 yum 装了一个编译工具或一个静态二进制,怎么把它用在宿主机上?这里分几种情况。
如果只是需要一个命令行工具,可以用docker cp把容器里的可执行文件拷出来。比如:
# 先让容器在后台运行 sudo docker run -d --name mycentos rockylinux:9 sleep 3600 # 在容器里安装软件 sudo docker exec mycentos yum install -y htop # 把可执行文件拷出来 sudo docker cp mycentos:/usr/bin/htop /usr/local/bin/htop但这种方法只对静态依赖较少的工具有效。像 htop 这种依赖系统库的工具,直接拷到 Ubuntu 上很可能因为找不到.so库而出错。更靠谱的方式是用卷挂载,把宿主机的某个目录挂到容器里,让容器把编译产物或安装包写到这个共享目录:
sudo mkdir -p ~/rpm_share sudo docker run -it --rm -v ~/rpm_share:/data rockylinux:9 bash进入容器后,/data目录对应的就是宿主机的~/rpm_share。你在容器里执行的任何写操作,都会直接出现在宿主机上,非常方便。
6.3 没有 Docker 时的替代方案:虚拟机
如果你所在的网络环境不允许安装 Docker,或者你不想引入额外的运行时,另一个办法是直接用虚拟机装一个 CentOS/Rocky。这个方案最重,但最真实,适合需要长时间在 RPM 环境里做开发、调试的场景。
虚拟机里配置 yum 源时,很多人会踩到“源不可用”的坑。比如 CentOS 7 已经停止维护,默认的 mirrorlist 可能全部失效,需要把 BaseOS、Extras 等源切换到阿里云等镜像站或者 vault 仓库。这个跟 Ubuntu 的报错虽然表现形式不同,但本质一样:都是仓库地址不可达或未配置。思路殊途同归,都是确认仓库文件路径、确认 baseurl 有效、然后 repolist 验证。
7. 常见问题与排查技巧实录
7.1 错误现象速查表
| 现象 | 可能原因 | 解决方向 |
|---|---|---|
| yum install 报 There are no enabled repos | /etc/yum.repos.d/ 下没有 enabled=1 的仓库文件 | 配置仓库,或改用 apt |
| yum repolist all 输出里仓库前有感叹号或显示 disabled | 仓库文件里 enabled=0,或变量解析失败 | 把 enabled 改为 1,排查 $releasever 等变量 |
| yum install xxx 提示 No package xxx available | 仓库里确实没有这个包,或架构不匹配 | 换仓库源,或确认 rpm 包架构是 x86_64/arm64 |
| apt install 报 Package xxx has no installation candidate | 软件源没刷新或源里没有 | apt update,或添加 PPA 源 |
| 在 Ubuntu 上执行 apt update 有 404 错误 | sources.list 里用的版本代号不对 | cat /etc/os-release 确认版本,修改代号 |
| 使用 yum 安装 rpm 包后系统库文件被覆盖 | 混用 yum 和 apt 导致依赖冲突 | 立即恢复被覆盖文件,下次用容器方案 |
7.2 排查 yum repo 问题的三条命令
遇到 yum 仓库相关的疑难杂症,我通常按顺序执行三条命令,基本能定位 90% 的问题。
第一条是yum repolist all,看所有仓库的状态。输出中enabled表示启用,disabled表示未启用,状态前有感叹号可能是变量问题或地址无法解析。
第二条是yum repolist --verbose,它会输出仓库的详细信息,包括 baseurl、优先级、是否有 GPG key 等。这个命令在判断“为什么仓库没有生效”时非常有用。
第三条是yum -v repolist,或者直接用yum clean all清理缓存后重试。有时候仓库元数据在第一次加载时失败了,清理缓存后重新解析就正常了。
7.3 一个经常被忽略的权限问题
.repo文件如果在/etc/yum.repos.d/下,普通用户执行yum repolist时可能加载失败。虽然 yum 通常能读取 root 创建的文件,但如果你手动创建仓库文件时用了错误的 SELinux context,或者文件权限是 600 且属于某个普通用户,yum 可能会出现“仓库被跳过”的行为。
在 Ubuntu 上虽然默认没有 SELinux,但文件权限问题依然可能存在。建议创建完成后统一执行:
sudo chmod 644 /etc/yum.repos.d/local.repo sudo chown root:root /etc/yum.repos.d/local.repo这个小细节,能避免不少莫名其妙的问题。
8. 从一次报错看包管理器的设计哲学
8.1 报错本身就是一种保护机制
There are no enabled repos这个提示,比很多错误提示都要直白。它的潜台词是:你让我装东西,但我没有可用的获取来源,我不能凭空变出软件包。这种“没有来源就拒绝执行”的设计,本质上是为了避免用户在当前系统状态下进行不确定的操作。
类比一下,你让一个厨师做菜,但厨房里没有食材,厨师当然会说“我什么都做不了”。这时候你要做的不是逼厨师做菜,而是决定是去采购食材,还是换一家有食材的餐馆。放到系统这里就是:要么给 yum 配仓库(采购),要么换成 apt(换餐馆),要么开容器(去另一家餐馆吃)。
8.2 好的工具选择是“顺势而为”
我在实际维护服务器的过程中,越来越体会到一件事:发行版和包管理器是一套强绑定的生态。Ubuntu 的生态是 deb + apt,CentOS/Rocky 的生态是 rpm + yum/dnf。强行在 Ubuntu 里塞 yum,就像给一辆柴油车加了汽油,短期可能没熄火,但长期一定会积碳。
所以我的核心建议永远是:在哪个系统,就用哪个系统的工具链。遇到只有 rpm 包的情况,优先想办法转换成 deb,或者用容器隔离,而不是把包管理工具本身移植过去。这个思路适用于 Ubuntu,也适用于其他发行版。
9. 最后的经验与一个小技巧
这个There are no enabled repos的报错,我前前后后遇到过不下十次,自己也曾在 Ubuntu 上折腾过给 yum 配源的路子。现在我的处理习惯已经固化成三步:先cat /etc/os-release确认系统身份,再ls /etc/yum.repos.d/看仓库配置,最后直接决定是用 apt 还是开容器。整个流程不超过一分钟。
最后分享一个小技巧:如果你是从 CentOS 刚切过来,短期内控制不住想敲 yum 的手,可以在~/.bashrc里加一个提示:
alias yum='echo "This is Ubuntu, use apt instead."; sudo apt'这样你每次敲 yum,终端都会先警告你一句,然后自动帮你执行 apt。等你完全习惯了 apt 的节奏,再把这个 alias 删掉就行。我不建议长期保留这种 alias,因为它会掩盖两个系统的差异,让你永远记不住正确的命令。但作为过渡期的手腕,实测确实好用。