很多刚接触 Linux 的朋友,拿到一台服务器,或者刚装好一台虚拟机,第一句话问我的常常是:“怎么装软件?”第二句话十有八九是:“这个 vi 怎么退出?”这两句话,恰好就是 yum 和 vim 这两个基础工具要解决的问题。yum 管软件的安装、卸载和依赖关系,vim 管文件的查看、修改和代码编写。标题里写着“基础开发工具”,但真正用起来你就会发现,它们是每个 Linux 用户几乎每天都要碰的东西。
我见过不少人因为 yum 源没配好装不上包,因为不知道 vim 怎么保存退出,最后干脆放弃命令行回到图形界面。这和智商没关系,纯粹是没人把原理讲清楚,也没人告诉你踩坑之后怎么爬出来。所以我这篇文章不打算只堆命令,而是尽量把“为什么这么配”“报错到底在说什么”一起讲透。哪怕你是第一次接触 Linux,照着做也能把一套常用的开发环境搭起来,并且以后再遇到类似问题,心里会有一个清晰的排查方向。
1. 先搞清楚这两个工具到底解决什么问题
1.1 刚拿到 Linux 环境,最先崩心态的两件事
第一件事是装软件。你敲一个 yum install xxx,系统要么提示找不到包,要么提示依赖缺失,要么干脆卡在那里不动。很多初学者到这里就懵了,以为是命令敲错了,其实是 yum 源没有配置好,或者系统不知道该去哪里找这个软件包。说白了,yum 本身只是一个“客户端”,它要去你指定的仓库地址拉取软件信息,仓库没配对,后面全白搭。
第二件事是改文件。你用 vim 打开一个配置文件,发现方向键变成了 ABCD,不知道按什么才能退出,一不小心还把文件改乱了。这个体验确实不友好,但它是可以完全解决的。你只需要理解 vim 的模式机制,它其实比你在图形界面里点点点要高效得多。
1.2 yum 和 vim 的分工,以及为什么它们绕不开
yum 解决的是“软件从哪里来、缺了什么依赖、怎么升级和卸载”的问题。Linux 不像 Windows 那样一个 exe 双击完事,软件包之间牵扯着大量的依赖关系,yum 这类包管理器就是专门来解决这个麻烦的。
vim 解决的是“文件怎么改”的问题。你可能会说现在有 VS Code、有 IDEA,为什么还要用 vim?因为生产环境里的服务器绝大多数没有图形界面,你 ssh 上去之后,唯一能用的可靠编辑器就是 vim 这一族。不管是改 Nginx 配置、改 yum 源、写一段脚本,还是临时看一段日志,vim 都是最稳妥的选择。
1.3 这篇文章要带你看完什么
下面我会先讲 yum 的仓库原理、三种主流源配置场景,再讲本地源的完整配置步骤;然后进入排错环节,把最常见的 yum 报错和排查链路拆开来看;接着进入 vim 的模式思维和命令速查,再做一些高频实操,比如多行注释、全选复制、批量替换;最后用一套“用 vim 配 yum、用 yum 装工具链、再用 vim 写代码编译”的组合流程,把这两个工具串起来。你会发现,它们不是孤立的知识点,而是同一个工作流里的前后环节。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. yum:从“装不上”到“装得明白”,关键是理解仓库
2.1 yum 不是自己会装软件,它背后有一个“仓库”
你可以把 yum 想象成一个手机应用商店。商店本身不自带软件,它需要连接服务器,服务器上放着大量打包好的 rpm 包,以及一份描述这些包的信息清单。yum 运行时,先读取这份清单,你告诉它要装什么,它就根据清单计算依赖关系,然后把需要的包和依赖一起下载安装。
仓库的地址写在哪?在 /etc/yum.repos.d/ 目录下的 .repo 文件里。系统中可以同时存在多个仓库文件,每个文件里可以配置多个 [仓库名] 段落。你执行 yum repolist 看到的就是当前启用的仓库列表。
仓库地址也可以指向多种来源:可以是互联网上的镜像站,可以是本地磁盘里的 ISO 镜像,也可以是公司内网搭建的私有仓库。不管哪种,核心要素都一样:仓库名、baseurl(包实际存放地址)、enabled(是否启用)、gpgcheck(是否校验数字签名)。baseurl 这个词值得多一点关注,后面我们配置本地源的时候,所有工作围绕的都是把 baseurl 指向一个正确的位置。
2.2 先查一下你的系统现在用的是哪个源
拿到一台新机器,别急着装东西,先看看当前的源状态:
bash复制yum repolist
这个命令会列出所有启用的仓库 ID、名称和可用软件包数量。你也可以直接查看目录内容:
bash复制ls /etc/yum.repos.d/
CentOS 7 默认的 CentOS-Base.repo、openEuler 的 openEuler.repo、麒麟 V10 里的各种 Kylin-*.repo,大同小异。如果你发现某个仓库的软件包数量是 0,或者执行 yum install 时显示 "No package xxx available",那大概率就是仓库地址失效了、路径不对或者元数据没拉取成功。
另外两个高频查询命令也顺手说一下:
bash复制yum search 关键词 # 不知道包名时,先搜
yum provides */命令名 # 反查某个命令是哪个包提供的
比如你输入 python3 发现没这个命令,但不确定应该装哪个包,就可以用 yum provides */python3 去查,它会告诉你属于 python3 这个包,可以直接装。这个反查技巧在排查“命令找不到”的问题时非常管用。
2.3 三种 yum 源配置场景怎么选
根据环境不同,我一般把源换成以下三类。新手先别急着照抄网上一键脚本,最好手动配一次,搞清楚每个字段是什么意思,否则出了问题连排查也无从下手。
| 源类型 | 适用场景 | 配置要点 | 常见坑 |
|---|---|---|---|
| 系统默认源 | 刚装完系统、外网可达 | 一般不用动 | 部分发行版默认地址速度慢,或官方源停止维护后失效 |
| 国内镜像源 | 日常开发、服务器可访问外网 | 替换 baseurl 为镜像站地址,保留 gpgcheck |
路径要对应版本号,写错一级目录就找不到包 |
| 本地源 | 离线环境、内网环境、反复装系统 | 挂载 ISO 或内网同步目录,baseurl=file:// 路径 |
需要 createrepo 生成元数据,否则 yum 不认 |
服务器能访问外网时,优先把源换成国内镜像站,比如阿里云、清华大学 TUNA、中科大 USTC 的源。推荐做法的核心是:绕过默认源,把 baseurl 改成镜像站提供的地址,其他字段保留原样。比如 CentOS 7 的 base 源,镜像站地址通常长这样:
bash复制baseurl=http://mirrors.aliyun.com/centos/7/os/x86_64/
注意最后的 7/os/x86_64/ 是有讲究的,它对应大版本号、软件类别和 CPU 架构。如果你的机器是 ARM 架构,就要换成 aarch64。这大概是配源时最容易翻车的地方。
2.4 本地 yum 源完整配置实操:离线环境的救命操作
离线或内网环境是最考验 yum 配置能力的场景。下面这套步骤我实际验证过多次,在 CentOS 7、麒麟 V10、openEuler 等基于 RPM 的发行版上基本通用。
第一步:拿到 ISO 镜像文件并挂载
bash复制mkdir -p /mnt/cdrom
mount -o loop /path/to/系统镜像.iso /mnt/cdrom
如果你用的是虚拟机,也可以直接把 ISO 挂到虚拟光驱上,然后 mount 光驱设备。挂载完成后,看看目录里有什么:
bash复制ls /mnt/cdrom/
正常的安装镜像里会有 Packages 或 BaseOS 目录。CentOS 7 的镜像里,repodata 目录和 Packages 目录是分离的,你直接能看到很多 rpm 包;而 RHEL 9 或 openEuler 新版镜像的目录结构可能不同,需要先确认软件包实际存在哪一级目录里。
第二步:生成或确认仓库元数据
yum 能在某个目录里找软件,前提是这个目录的 repodata 目录中必须有元数据文件。CentOS 7 的 ISO 自带 repodata,挂载后直接可用。如果 iso 里没有,或者你准备用一个网络同步下来的 rpm 目录做本地源,就需要手动生成:
bash复制yum install -y createrepo
createrepo /mnt/cdrom
如果系统完全离线装不了 createrepo,也可以在 ISO 的 Packages 目录里找到 createrepo 对应的 rpm,用 rpm -ivh createrepo-*.rpm 手动安装,依赖缺失时顺便把依赖也一起装上。
第三步:编写 repo 文件
用 vim 新建一个本地源配置文件:
bash复制vim /etc/yum.repos.d/local.repo
内容如下:
bash复制[local]
name=Local Repository
baseurl=file:///mnt/cdrom
enabled=1
gpgcheck=0
写完 :wq 保存退出。这里的 baseurl=file:///mnt/cdrom 就是“把源更换到本地地址”的直接体现。file:// 前缀表示本地文件协议,后面跟绝对路径。
第四步:清理缓存并验证
bash复制yum clean all
yum makecache
yum repolist
如果能看到 local 仓库且包数量正常,说明本地源已经生效。这时候再执行 yum install 任意包名 就能从本地 ISO 里安装了。gpgcheck 我通常在内网环境设为 0,省去导入密钥的麻烦;但在安全要求严格的生产环境,建议设置 gpgcheck=1 并配置正确的 gpgkey 路径。
3. yum 报错时的完整排查链路:从源失效到依赖冲突
3.1 源地址连不上,怎么判断是网络问题还是仓库问题
yum install 最常见的报错就是找不到仓库地址,比如:
bash复制Could not resolve host: mirrors.xxx.com
Cannot retrieve metalink for repository: epel
看到这种报错先别急着换源。我的排查顺序是:先确认网络通不通,再确认仓库地址通不通。用 curl 直接测源地址:
bash复制curl -I http://mirrors.aliyun.com/centos/7/os/x86_64/
如果 curl 能返回 HTTP 状态码,说明地址没问题,问题可能出在 yum 缓存或者源文件配置上;如果 curl 本身就超时,那就要检查机器能不能上网,看 /etc/resolv.conf 里 DNS 配置是否正常。很多服务器换了网络环境之后没有重启 network 服务,导致 DNS 解析不了域名,这时 ping 网关通、ping 域名不通,就能快速定位。
另外我见过不少同学把镜像站地址抄错,少写一层目录,比如 baseurl=http://mirrors.aliyun.com/centos/7/ 而不是完整的 .../os/x86_64/。yum 找不到目录里的 repodata 时,就会报 "Could not find a valid baseurl" 这类错误。所以测地址的时候,确保浏览器或 curl 能直接访问到 repodata 目录的上一级,这样才算真正配对了。
3.2 公钥校验失败:gpgcheck 不是随便设的
安装软件时偶尔会看到这样的提示:
bash复制Public key for xxx.rpm is not installed
这是 yum 在下载完 rpm 包后做签名校验,发现本地没有对应的公钥。解决方式有两种。一种是临时绕过校验,只装这一次:
bash复制yum install --nogpgcheck <包名>
另一种是正规做法,把仓库签发公钥导入系统:
bash复制rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-*
然后在 repo 文件里写明 gpgkey 路径。不同发行版公钥文件名不一样,CentOS 和 openEuler、麒麟各有各的命名,你可以在 /etc/pki/rpm-gpg/ 目录下找到。我这里建议是把 gpgcheck 当成一个安全开关认真对待,日常在可信源上保持 gpgcheck=1;只有本地离线源图省事时才设为 0,因为离线源中的包来源唯一且可控。
3.3 缓存引起的玄学报错,先 clean all 再 makecache
有时候你明明改了 repo 文件,重新安装却发现 yum 还在用旧地址,甚至提示仓库列表为空。这种十有八九是缓存问题。yum 会把仓库的元数据缓存到本地,如果你源文件改了但没清缓存,它读的还是旧数据。
标准处理办法就两步:
bash复制yum clean all
yum makecache
清理之后重新生成缓存,再执行 yum repolist 验证。这个地方没有多少技术含量,但排在排查顺序的前面,因为成本最低、收益最快。我自己的习惯是:只要改过任何 repo 文件,下一步绝对是 clean all + makecache,不会直接去 install。
3.4 依赖冲突、多版本保护,怎么定位到具体冲突
再复杂一点的报错是事务检查阶段的冲突:
bash复制Transaction check error:
file /usr/bin/xxx conflicts between attempted installs of A and B
Protected multilib versions: C-1.0-1.x86_64 vs C-1.0-1.i686
这种通常是多个源里存在同名包的不同版本,或者一个 32 位一个 64 位的包在抢占同一个文件路径。遇到这种问题,第一反应应该是缩小启用的源范围,而不是直接卸载系统包。
比如你既开了本地源又开了默认源,两个源里的 gcc 版本不一致,就可能冲突。可以先看依赖关系:
bash复制yum deplist <包名>
然后指定只用某个源来安装:
bash复制yum --disablerepo=* --enablerepo=local install <包名>
通过 --enablerepo 和 --disablerepo 组合,只允许某一个仓库提供软件,能快速隔离冲突源。如果已经装到一半发现不对劲,可以用 yum history 查看事务历史,再 yum history undo <事务ID> 回滚。这套思路比盲目 rpm -e 安全得多,我见过有人手抖删了 glibc,最后系统直接起不来,教训极其深刻。
3.5 总结一套稳妥的排错顺序
经验多了之后,yum 报错基本逃不出这几个方向。我固定按以下顺序排查:
- 看网络和 DNS:
curl测 baseurl 是否可达。 - 看源文件:路径是否写到了正确的版本和架构目录。
- 清理缓存:
yum clean all后重新makecache。 - 看 gpgkey 和 gpgcheck 是否匹配。
- 看多仓库冲突:用
--disablerepo缩小范围。 - 回滚:用
yum history而不是rpm -e。
这套顺序我基本没失手过,只要按着走,绝大多数问题十分钟内能定位。
4. vim:先掌握模式思维,再谈命令效率
4.1 模式才是 vim 的灵魂
很多新手打开 vim 之后乱按一通,然后又退不出来,核心原因是没有理解“模式”。vim 不是像记事本那样打开就能直接打字,它默认进入的是普通模式。在这个模式里,键盘上的每个字母都是一个命令,而不是要输入的文字。比如按 j 是光标向下移动一行,按 x 是删除光标所在字符,按 i 才进入插入模式开始打字。
普通模式、插入模式、可视模式、命令行模式,这四种模式构成了 vim 的全部交互方式。普通模式是所有操作的起点和终点,插入模式只是负责“写字”的一个短暂环节。你可以把它想象成一台相机的 M 档:先拨盘设置参数,再按快门拍摄,而不是一开机就一直拍个不停。刚开始会觉得别扭,但一旦习惯,你会发现自己根本不想回到鼠标上。
4.2 先把这三个“新手劝退点”解决掉
第一,不知道如何退出。按 Esc 回到普通模式,然后输入 :q! 强制退出不保存,wq 保存并退出,ZZ 保存退出。把这三个记熟,至少你不会被困在 vim 里。
第二,方向键变成 ABCD。这通常是系统自带 vi 而不是完整版 vim 导致的老问题。解决办法很简单:安装 vim-enhanced,之后用 vim 命令替代 vi。安装命令正好用上章学的 yum:
bash复制yum install -y vim-enhanced
第三,误操作把文件改乱了。别慌,按 Esc 进入普通模式,按 u 撤销,或者直接 :q! 退出不保存。vim 的哲学之一就是允许你随时反悔,这一点比很多图形编辑器做得更好。
4.3 移动、编辑、删除、复制的命令速查
新手不需要一下子记几百条命令,先把下面这份最常用的表吃透,效率就比在记事本里高出一大截。
| 操作类型 | 命令 | 说明 |
|---|---|---|
| 移动光标 | h j k l |
左、下、上、右 |
| 单词跳跃 | w b |
跳到下一个 / 上一个单词开头 |
| 行内移动 | 0 $ |
跳到行首 / 行尾 |
| 全文移动 | gg G |
跳到第一行 / 最后一行 |
| 翻页 | Ctrl+d Ctrl+u |
向下 / 向上翻半页 |
| 进入插入模式 | i a o |
光标前插入 / 光标后插入 / 下方新开一行 |
| 删除 | x dd dw d$ |
删字符 / 删整行 / 删单词 / 删到行尾 |
| 复制粘贴 | yy p P |
复制整行 / 粘贴到下方 / 粘贴到上方 |
| 撤销重做 | u Ctrl+r |
撤销 / 重做 |
| 查找 | /关键字 n N |
向下查找 / 下一个 / 上一个 |
真正用起来的时候,0、$、w、b、gg、G 这六个移动命令的使用频率远高于其他。我建议你把光标移动练到不需要思考,因为编辑的前提是“指哪打哪”,光标都跑不准,后续所有操作都别扭。
4.4 理解“动词 + 对象”的语法,比背命令更重要
vim 里真正强大的不是单条命令,而是一套组合语法。你不需要记住成百上千条命令,只需要掌握几个动词和几个对象,就能组合出大量操作。
常用的动词有:d(删除 delete)、y(复制 yank)、c(修改 change)、v(进入可视模式选择)。常用的对象有:w(单词)、$(到行尾)、0(到行首)、gg``G(全文)、i w(整个单词 inside word)。
组合起来就能看懂很多操作了:
d w:删除一个单词。d $:删除从光标到行尾。y y:复制整行。c i w:修改整个单词(先删除这个词并进入插入模式)。d d:删除整行,不用先选中。
理解这套语法之后,你看见一个陌生的命令组合,往往能猜出它的意思。这比死记硬背高效得多,也是 vim 从“能用”变成“好用”的关键一步。如果零基础想系统性练,vimtutor 是老牌入门教程,vim 大冒险这类游戏化工具也可以帮你快速建立手感,但核心还是把模式思维刻进脑子里。
5. 高频 vim 操作实战:多行注释、全选复制、批量替换
5.1 一次注释多行,怎么选都行
“vim 一次注释多行”是群里被问爆的问题,尤其在写脚本的时候,一段配置想临时注释掉,手动一行行加 # 真的很崩溃。最直观的做法是用可视块模式:
- 把光标移到要注释的第一行行首,按
Ctrl+v进入可视块模式。 - 用
j/k上下移动,选中多行。 - 按
I(大写的 i),输入#。 - 按 Esc,你会看到所有选中行首都出现了
#。
取消注释同理,再次 Ctrl+v 选中包含 # 的列,按 x 即可删除。另一种思路是用替换命令:
bash复制:%s/^/#/
这会把每一行的行首 ^ 替换成 #。取消注释就用 :%s/^#//。如果你只想注释第 10 到 20 行,把 % 换成 10,20s 就行。我在实际工作中两种方式都会用,可视块方式适合临时注释几行,替换方式适合批量处理大范围。
5.2 全选复制与“lines yanked”提示
在 vim 里按下:
bash复制gg V G
gg 跳到第一行,V 进入可视行模式,G 跳到全文末尾。此时全文已被选中,然后按 y 复制。vim 底部会提示类似 10 lines yanked,意思是 10 行已经复制到寄存器里了。很多人看到 “lines yanked” 会懵,其实 yank 就是 vim 对“复制”的叫法。
如果只是复制几行,不需要全选,把光标移到目标行后按 yy 复制一行,再用 5yy 复制连续 5 行,粘贴用 p。如果你想把 vim 里的内容复制到系统剪贴板,也就是复制完能在浏览器、终端里粘贴,需要使用:
bash复制"+y
双引号加号表示系统剪贴板寄存器。如果这个命令没反应,说明你的 vim 版本没有编译剪贴板支持,用 vim --version | grep clipboard 可以确认,不带 +clipboard 就需要换装 vim-enhanced 或带图形支持的 vim 包。
5.3 批量替换:从改一个到改全部
批量替换是 vim 里最高频又最容易被忽略的技能。比如你把配置文件里所有 8080 端口改成 9090,一条命令就能搞定:
bash复制:%s/8080/9090/g
% 表示全文,s 是替换,最后的 g 表示一行内所有匹配都替换。如果不加 g,vim 默认只替换每行第一个匹配,这是很多新人踩坑的地方。
如果你只想看每一处在替换前确认一遍,加上 c:
bash复制:%s/8080/9090/gc
vim 会逐个提示是替换、跳过还是全部替换。这个功能在重构代码、替换变量名时尤其好用,因为有些替换可能不希望你盲目改动。如果替换的内容里包含路径分隔符 /,可以把分隔符换成其他符号,比如 #:
bash复制:%s#/opt/old#/opt/new#g
这些小细节多记几个,改配置文件的效率会有质的提升。
5.4 粘贴缩进错乱和系统剪贴板问题
用 vim 粘贴一段多行代码时,经常出现缩进越来越离谱的情况。原因是 vim 开启了自动缩进,粘贴进来的文本会被它重新“格式化”,结果格式全乱了。解决办法是在粘贴前关掉自动缩进:
bash复制:set paste
粘贴完成后恢复:
bash复制:set nopaste
更优雅的方案是在 .vimrc 里配置一键切换:
bash复制set pastetoggle=<F2>
以后按一下 F2 就切换 paste 模式,状态栏会有明显提示,粘贴完成再按一次切回来。这个坑我踩过很多次,现在基本把它当成 vim 必备配置了。
6. 用 vim 配 yum、用 yum 装工具链:一台开发机的完整落地流程
6.1 先用 vim 把源源文件写好
把前面所有知识串起来的场景,应该是这样的:你拿到一台全新的 Linux 机器,第一步是把它配置成能用的开发环境,而最先要做的就是用 vim 写 yum 源文件。
比如配置一个本地源:
bash复制vim /etc/yum.repos.d/local.repo
在 vim 里输入以下内容:
bash复制[local]
name=Local Repo
baseurl=file:///mnt/cdrom
enabled=1
gpgcheck=0
保存退出后执行:
bash复制yum clean all
yum makecache
这里要注意一个容易忽略的细节:改完 repo 文件后,必须先确认保存成功(检查 :wq 是否执行成功),再去执行 yum 命令。我见过有人因为 vim 里按了 :q 没保存,结果 yum 用了半天还是旧源,怎么排查都不对。所以在整个流程里,“vim 写文件”和“yum 读仓库”是紧密衔接的两步,任何一步出错,后面都不通。
