ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Linux离线安装vim全攻略:yum与apt依赖打包及本地源搭建

Linux离线安装vim全攻略:yum与apt依赖打包及本地源搭建 1. 核心逻辑为什么需要离线安装以及什么场景才值得折腾先说结论搞离线安装绝大多数时候不是技术问题而是环境问题。你在开发机上一条yum install -y vim敲下去秒装完根本轮不到搞什么离线包。真正需要这套流程的是下面这几类人第一类是内网和生产环境运维。公司内网服务器往往和互联网物理隔离或者只对特定网段开放白名单你不能为了装一个 vim 就去申请防火墙策略。第二类是等保、密评等合规要求下的现场交付客户环境严格锁定不允许随意引入外部源。第三类是简单的网络不给力比如某些云主机访问官方镜像源常年超时与其等yum makecache卡上半小时不如在本地一次性准备好离线包。但我得说实话vim 本身是一个非常小的工具依赖也相对收敛。你会来搜“离线安装 vim”大概率在意的不是任务量而是这套“下载依赖包—打包—内网安装”的通用方法论。这套方法会了以后不只是 vim像 gcc、nginx、docker 这些动不动就带几十上百个依赖的东西你也能照葫芦画瓢搞定。还有一点你要清醒yum和apt是两套完全不同的包管理逻辑。yum 对应 RPM 体系的 CentOS / RHELapt 对应 DEB 体系的 Ubuntu / Debian。它们的临时缓存目录、依赖打包方式、离线安装命令都不一样。接下来我会把两条线都讲透你在实操前先确认自己手上是哪条线别拿 CentOS 的思维去 Ubuntu 上硬套反之亦然。注意如果你只是在自己电脑的 VMware / WSL 里想装个 vim千万别折腾离线方案直接yum install或apt install走官方源是最高效、最稳妥的路径。离线安装是给受限环境准备的。2. 思路分层三种离线安装方案按场景选型离线安装 vim 不是一个单一方案而是根据“源机器和离线机器是否同架构、依赖规模多大、以后还要不要装别的包”这三个因素分为三个层级。层级一最简单口粮方案——只拷贝 vim 一个 RPM/DEB 包。这个方案只适合目标机器缺少 vim且它的大部分依赖已经存在的情况。比如你在 CentOS 7.9 上执行过yum install -y vim-enhanced系统里已经自动装好了vim-common、vim-filesystem等子包。这时如果另外一台同版本系统没有 vim你只需要找到那台已装机器上的 vim 主包拷贝过去rpm -ivh vim-enhanced*.rpm即可。但这种情况比较少见因为干净的机器往往连着底层依赖也一起缺失。层级二使用 yumdownloader / apt download只下载而不安装。这种方案会在当前机器上下载 vim 本包和所有依赖包存到指定目录然后打包拷走。核心是“借用一台联网机器作为下载代理”不污染代理机器的系统环境也不要求代理机器和目标机器有相同的已装软件状态。几乎所有离线安装教程都止步于此但它有个隐藏问题你没法保证下载到的依赖列表是完整闭环的。假设代理机器上已经装了某个依赖库yumdownloader会认为“这个包已经满足”从而不把它拉下来到了目标机器上照样缺。要绕过这个问题就得想办法让下载过程强制解析完整依赖集合后面我会讲到用--resolve加临时清空本地已装状态这类技巧。层级三同步完整仓库到本地做成内部离线 yum/apt 源。用reposyncCentOS或apt-mirrorUbuntu把整个仓库同步到一台内网服务器然后搭建本地文件源或 HTTP 源。这个方案重量级但一劳永逸。你不仅能在内网装 vim以后任何包都可以直接yum install因为系统已经把所有包都准备好了。对于有独立内网机房的团队我强烈推荐这个方案。缺点是首次同步的数据量大CentOS 7 的 base 源加 epel 源通常要 50GB 以上哪怕只同步 base 源也要十几个 GB。我的建议如果你只是要解决“今天把 vim 装上”这个一次性任务选择方案二如果你知道未来半年还会在内网装很多环境老老实实搭建方案三节省的总时间绝对远超搭建成本。3. CentOS 离线安装 vim 的完整实操yum 体系3.1 前期排查确认版本、架构与依赖现状在动手下载之前先做三件事。第一步确认系统版本和架构。目标机器和下载机器的 CentOS 大版本必须完全一致小版本最好也一致。CentOS 7.9 的 RPM 包如果强行装到 CentOS 8 上较轻的后果是依赖冲突装不上较重的后果是 glibc 版本不匹配导致程序运行时直接段错误。架构方面x86_64 的包不能装在 aarch64 的机器上也不要混用 i686。命令如下cat /etc/redhat-release uname -m第二步检查目标机器上是否已经装了 vim 的某些子包或冲突包。如果系统里已经有vim-minimalCentOS 默认自带用于支持/usr/bin/vi装 vim-enhanced 时通常能共存不会起冲突。但如果你之前从源码编译过 vim二进制放在了/usr/local/bin那么打包安装后新 vim 可能不会生效因为 PATH 里/usr/local/bin通常排在/usr/bin前面。第三步在联网机器上确认源可用。如果 yum 源本身都失效了后面所有步骤都无从谈起。检查方法yum repolist yum list available vim-enhanced3.2 主推方案yumdownloader 加依赖打包这个方案的实际效果是在联网机器上把 vim-enhanced 连同它依赖的所有 RPM 集中下载到指定目录然后拷走。CentOS 7 默认可能没有安装yum-utils这个工具集需要先装或者直接用 yum 自带插件替代。先按下面命令装好工具yum install -y yum-utils然后建立目录并执行下载mkdir -p /opt/vim-offline cd /opt/vim-offline yumdownloader --resolve --destdir/opt/vim-offline vim-enhanced--resolve参数是关键它的作用是让 yumdownloader 像实际安装一样解析依赖关系然后把所有需要但系统里不存在的依赖包一并下载。不过前面提到过这个“依赖闭环”取决于当前系统的已装状态如果联网机器上已经预装了python3、ncurses-libs这些它们不会出现在下载列表里。严谨的做法是用一个干净的容器或虚拟机来执行下载操作。没有条件的话也可以先看下载结果里有没有包含vim-common、vim-filesystem这两个是 vim-enhanced 的核心子包。如果缺失极可能目标机器装的时候也会缺。下载完成后检查内容ls -lh /opt/vim-offline/正常情况你会看到类似vim-enhanced-7.4.629-8.el7_9.x86_64.rpm、vim-common-7.4.629-8.el7_9.x86_64.rpm、vim-filesystem-7.4.629-8.el7_9.x86_64.rpm、ncurses-libs-5.9-14.20130511.el7_9.x86_64.rpm这样一批包。3.3 依赖不完整时的补救用模拟安装抓取完整清单如果你下载后发现依赖包数量明显偏少或者拷贝到目标机器上安装时报“缺少依赖”这时候别慌可以用yum的模拟安装模式来获取完整依赖列表。在联网机器上执行yum install --assumeno vim-enhanced | grep Installing for dependencies输出里会列出“安装 vim-enhanced 会连带安装的所有依赖”。虽然--assumeno不会真正执行安装但 yum 在这一步已经完成了依赖解析。把列表里的每个包名记下来再用yumdownloader逐个下载yumdownloader --destdir/opt/vim-offline vim-enhanced vim-common vim-filesystem ncurses-libs ...注意yum install --assumeno输出的是“最终会安装的包清单”但不是“下载清单”。因为里面可能包含“已安装但需要更新”的包。对于离线环境我们不负责更新系统里已有但版本偏旧的包只负责补齐“完全不存在”的包所以下载时优先确保目标机器上不存在的那些。如果你没有条件判断目标机器装了什么最省心的方案是创建容器模拟目标环境在容器里用 yumdownloader 拉包。一个常见困惑是“目标机器里已有vim-minimal会不会和 vim-enhanced 的文件冲突”。从多年的实践经验看不会。vim-enhanced 提供/usr/bin/vimvim-minimal 提供/usr/bin/vi两者文件路径不重叠。但在极少数情况下依赖涉及vim-data比如 RHEL 9 的 vim 8.2就需要额外装这个新子包。3.4 目标机器执行安装与验证把整个/opt/vim-offline目录拷到目标机器上可以用 U 盘、scp、内网共享盘只要保证 RPM 文件齐全不损坏就行。然后在目标机器上执行cd /opt/vim-offline rpm -Uvh *.rpm一次安装所有包让 rpm 自行处理包间依赖。如果提示“需要 xxx 被 vim-enhanced 需要但 xxx 未安装”说明你的依赖包没下载全。这时候补下载对应包重新执行即可。如果提示“xxx 与已安装文件冲突”不要加--force硬刚先看清楚是哪个包冲突判断是否可以卸载旧包后重试。装完验证vim --version which vimvim --version能看到编译特性列表重点确认python3、clipboard等特性是否符合预期。默认源里的 vim-enhanced 通常不带 GUI但这对于绝大多数服务器场景足够用了。实测下来CentOS 7.9 上完整下载 vim-enhanced 的依赖包大约是 10 到 15 个 RPM 文件总计 40MB 左右一个 U 盘绰绰有余。3.5 拓展一条命令搞定 rpm 离线安装依赖补齐如果你不想用 yumdownloader还有一个更加原始但也更“所见即所得”的办法直接访问仓库的 repodata用repoquery递归查询依赖。yum install -y yum-utils repoquery --requires --resolve vim-enhanced这条命令会把 vim-enhanced 的完整依赖树全部列出来包括递归依赖不会受当前已装状态影响。把输出里每个包用yumdownloader拉下来和上面效果一致但更保险。4. Ubuntu 离线安装 vim 的完整实操apt 体系4.1 与 CentOS 的思维差异deb 是闭源格式但依赖解析更严格Ubuntu 的 deb 包体系和 RPM 体系最大的不同在于deb 的依赖记录非常严格但下载和安装是分离的。apt 默认把下载的 deb 文件缓存在/var/cache/apt/archives这个目录天然就是离线安装的素材库。理解这一点很有用你在联网 Ubuntu 机器上执行过一次apt install vim即使安装完成后/var/cache/apt/archives 里仍然保留着刚才下载的所有 deb 文件。把它们拷走就能直接离线装到另外一台同版本 Ubuntu 上。所以第一种 Ubuntu 离线方案其实是“运气好 早有准备”的方案适合在开发机上顺手做。但如果你是专程下载用apt download加apt-cache depends的组合或干脆用apt-get install --download-only一次性把依赖拉全。4.2 主推方案apt-get download-only 配合依赖解析在联网 Ubuntu 机器上确认版本信息lsb_release -a uname -mUbuntu 的包和系统版本强绑定。Ubuntu 20.04focal的 vim deb 包不能直接用于 Ubuntu 22.04jammy强行安装大概率会因为依赖的 libc6、libpython3.x 版本不符合要求而被拒绝。执行下载mkdir -p /opt/vim-offline-deb cd /opt/vim-offline-deb apt-get install --download-only --yes vim这几条命令的效果是把 vim 及其所有依赖 deb 下载到当前机器的 apt 缓存目录但不会安装。此处有两个细节第一--download-only意味着不安装但需要用户确认是否继续加--yes是跳过确认。第二下载完成后真正的 deb 文件在/var/cache/apt/archives里不是你在命令行所在目录能看到的。需要把缓存目录里的文件拷贝到工作目录cp /var/cache/apt/archives/*.deb /opt/vim-offline-deb/ ls -lh /opt/vim-offline-deb/另一种情况是你只需要下载 vim 单个包不关心依赖可以用apt download vim但它不会自动下载依赖。所以实际操作时更推荐--download-only方式。4.3 找出缺失依赖并补下载两种补充思路和 yumdownloader 类似apt-get install --download-only的结果同样受当前系统已装状态影响。如果代理机器上已经预装了某个共享库它就不会出现在缓存目录里。解决方案一用apt-cache depends查看 vim 的显式依赖然后逐个下载apt-cache depends vim输出里能看到 Depends 字段记录顶层依赖包名。不过 deb 的依赖分得更细有些是 PreDepends有些是 Recommends普通用户容易漏。用apt-cache depends时最好把Recommends的包也算上离线环境没有网络去补这个。解决方案二用干净容器下载到彻底docker run --rm -it ubuntu:20.04 bash apt update mkdir /opt/deb cd /opt/deb apt-get install --download-only --yes vim cp /var/cache/apt/archives/*.deb /opt/deb/ exit docker cp 容器ID:/opt/deb /host/download容器里的系统是干净的apt 解析依赖时会认为所有包都不存在从而完整下载。这个方案对离线依赖闭环最友好成本是 Docker 可能不是每个人都装了。个人建议小任务没必要引入 Docker用--download-only加手动检查依赖即可大批量离线部署或者要装大型软件时再用容器隔离。4.4 在离线 Ubuntu 上的安装与验证将整个/opt/vim-offline-deb目录拷贝到目标机器然后执行cd /opt/vim-offline-deb dpkg -i *.debdpkg 安装 deb 时不会自动拉依赖如果中间报依赖错误也先别慌。分两种情况如果错误提示是depends on xx but it is not installed说明你确实漏了包如果错误提示是depends on xx but it is not going to be installed说明 deb 之间的版本关系不匹配优先检查目标机器系统版本和下载机器是否一致。dpkg 报依赖错误后可以用一个经典补救apt-get install -f它会在本地缓存目录里自动搜索并尝试修复依赖。但注意-f修复如果目标机器完全离线没有网络源就会失败它只有在从网上源能拉到缺失包或缓存目录里已经有对应包时才有用。安装成功后验证vim --version dpkg -l | grep vim正常会显示ii vim 2:8.2.3995-1ubuntu2.21 amd64状态位ii表示正常安装。如果显示iF或iU说明安装不完整或配置未完成。4.5 避坑说明千万别忘了 apt 源配置与架构一致性离线安装最大的误区是以为 apt 源和在线安装没关系。实际上dpkg 安装 deb 包本身确实不需要网络但你在执行dpkg -i后如果调用了apt-get install -f那 apt 就会去读源配置。如果目标机器的/etc/apt/sources.list指向内网不存在的源-f修复会卡住等待超时。遇到这种情况要么临时把源列表备份后清空要么干脆不执行-f直接手动补齐缺失包。架构一致性同样关键。Ubuntu 的包命名中会包含amd64或arm64。arm64 设备比如树莓派、部分国产 ARM 服务器上强行装 amd64 的 debdpkg 会直接拒绝报“wrong architecture”。确认架构用dpkg --print-architecture。5. 批量需求场景搭建本地离线软件源5.1 CentOS 环境reposync 同步仓库并配置本地源如果团队内部有十几二十台 CentOS 机器都要离线装 vim或者后面还要装别的软件逐台拷贝 rpm 包显然不可行。这时候一次性做好本地 yum 源成本最低。搭建步骤在一台联网机器上安装 createrepo 和相关工具yum install -y createrepo yum-utils同步 base 仓库到本地目录这里以 CentOS 7.9 为例base 源mkdir -p /data/yum-repo/base reposync -r base -p /data/yum-repo/base-r指定仓库 ID-p指定同步目标。同步完成后用 createrepo 生成索引createrepo /data/yum-repo/base这一步会扫描目录下所有 RPM生成repodata目录yum 客户端正是依靠这个目录里的元数据来解析依赖。然后把整个/data/yum-repo目录挂到一台内网服务上用 Nginx 或 Apache 暴露 HTTP 服务或者简单点直接拷贝文件。在目标机器上新增源配置文件/etc/yum.repos.d/local.repo[local-base] nameLocal Base Repository baseurlfile:///data/yum-repo/base enabled1 gpgcheck0如果目标是 HTTP 访问把file:///data/yum-repo/base换成http://内网IP/yum-repo/base。配置完成后执行yum clean all yum makecache然后直接yum install -y vim-enhanced体验和在线没有任何区别。我的经验单纯为了 vim 做整个源更新是杀鸡用牛刀。但为了内网常态化运维这套搭建值得做。同步一次 base 加 epel 大概需要 30 到 80GB 空间和数小时时间建议放在晚上执行。5.2 Ubuntu 环境使用 apt-mirror 或简化的 deb 包目录Ubuntu 的本地源方案更灵活可以只下载需要的部分不一定同步全量仓库。假如你的内网机器都是 Ubuntu 20.04你可以在联网机器上执行apt-get install -y apt-mirror编辑配置文件 /etc/apt/mirror.list指定需要的发行版和组件比如############# config ################## set base_path /data/apt-mirror set nthreads 20 set _tilde 0 ############# end config ############## deb http://archive.ubuntu.com/ubuntu focal main restricted universe multiverse deb http://archive.ubuntu.com/ubuntu focal-updates main restricted universe multiverse deb http://archive.ubuntu.com/ubuntu focal-security main restricted universe multiverse然后执行apt-mirror。它会将指定的 deb 仓库同步到本地并生成目录结构。这里有个体验细节focal main全量同步大约 20 到 30GB只看时间不看总量通常几个小时能完成。完成后在目标机器上配置源指向内网服务器方式是把/etc/apt/sources.list改成deb [trustedyes] http://内网IP/apt-mirror/mirror/archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse光改列表还不够需要确保内网服务器存在对应路径的目录结构apt-mirror 默认的 mirror 目录路径是/data/apt-mirror/mirror/archive.ubuntu.com/ubuntuNginx 的 root 要指到 mirror 上层或者直接做一个软链。因为是内网环境trustedyes顺手加上避免公钥校验失败。同步后执行apt update apt install -y vim就能在内网机上直接安装。相比 CentOS 的 reposyncapt-mirror 的优点是自动处理目录结构缺点是首次配置稍微复杂且源路径容易配错。5.3 本地源的维护与常见目录坑搭建本地源“能用”很容易“长期好用”需要维护习惯。第一定期同步。CentOS 的 base 源变化频率不高一个月同步一次足够Ubuntu 的 updates 源变化频繁建议每周同步。同步前先把 repo 目录里旧的 repodata 删掉或备份防止索引混用导致依赖解析错误。第二务必保留 releasever 版本目录结构。很多人把 CentOS 源同步到本地后直接用 flat 目录导致目标机器上 yum 报Cannot retrieve metalink for repository。规范的做法是reposync同步时保留下7/8Server等版本目录这样 yum 客户端的$releasever变量能找到对应目录。第三gpgcheck 是个坑。本地源搭建时嫌麻烦会设gpgcheck0这在纯内网环境没问题。但如果内网有安全审计要求还是建议保留原来的 RPM-GPG-KEY在源文件里用gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7指定密钥。6. 常见问题与排查技巧实录6.1 依赖解析的“内存包”误差很多离线安装失败不是离线包缺了而是依赖解析阶段“误判”了目标机器上已有的软件组合。比如目标机器是一个瘦身过的基础镜像连glibc-common都没有而下载包时因为代理机器有glibc-common所以没下载最后导致 vim 起不来。排查思路在目标机器报缺依赖时先在目标机器执行rpm -q或dpkg -l查看依赖是否真的缺失然后再回下载机器补拉。不要盲目把报错里所有的依赖包都全量下载有些依赖包可能目标机器上有同名但版本略旧的强制升级会带来连锁影响。一个实用技巧在下载机器上临时卸载或屏蔽某些关键依赖包比如yum remove -y python3-libs会强制 yum 在后续下载时把 python3-libs 当作外部依赖重新纳入解析范围。这算是“模拟干净系统”的土办法效果和容器方案接近但会污染代理机器环境慎用。6.2 rpm 和 dpkg 安装冲突处理RPM 体系下最常碰到的冲突是 vim-minimal 的/usr/bin/vi路径与 vim-enhanced 的某些文档路径重叠。通常不会发生但在老版本 CentOS 6.5 上装高版本 vim 时容易遇到。我的建议是不要--force覆盖而是先把 vim-minimal 卸载rpm -e vim-minimal --nodeps rpm -Uvh vim-enhanced*.rpm卸载后如果出现which vi找不到命令可以手动创建软链ln -s /usr/bin/vim /usr/bin/videb 体系下的冲突通常发生在手动编译的 vim 和 apt 源里的 vim 之间dpkg -i会提示文件已存在且属于不同包。此时应该先手动删除编译安装的文件或直接卸载编译版本再执行 dpkg 安装。6.3 老系统CentOS 6.5 / RHEL 6的特殊处理CentOS 6.5 已经停止维护默认 yum 源都失效了。在这类机器上离线装 vim需要先解决“yum 源失效导致依赖解析失败”的问题。常见做法第一步把/etc/yum.repos.d/下官方源文件改名禁用只保留本地源mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak第二步创建本地源文件指向离线 RPM 目录参考第 5.1 节的配置。第三步CentOS 6 默认的 vim-minimal 是 7.2较老如果要装 vim-enhanced 需要确认版本兼容性。有些依赖包如 perl、ruby在老系统上版本过低即使离线包齐全也装不上这时候需要在下载机器上同样使用 CentOS 6.5 的仓库来拉包不要用 CentOS 7 的包。6.4 离线包的完整性校验拷包过程中最怕“拷一半损坏”。RPM 和 DEB 内部都有校验机制安装时如果文件损坏会直接报错但等到安装时才发现就浪费时间了。预防做法# RPM 校验 cd /opt/vim-offline rpm -K *.rpm # DEB 校验 cd /opt/vim-offline-deb dpkg-sig --verify *.deb 2/dev/null || echo deb 校验工具未安装可跳过rpm -K 会显示OK或MISSING KEYS前者表示校验通过后者只是缺少公钥但包完整性通常无碍。传输时用 tar 打包加 md5 校验更稳妥tar czf vim-offline.tar.gz /opt/vim-offline md5sum vim-offline.tar.gz vim-offline.md5内网传输后在目标机器执行md5sum -c vim-offline.md5。如果校验值不一致重新传输别硬装。6.5 没有联网机器时的替代思路如果有人问“我手头没有任何一台联网机器怎么离线装 vim”那最后的办法是利用目标机器上已有的其他工具链从源码编译。CentOS 通常自带 gccUbuntu 系统上则可能需要先确认 build-essential 是否完整。源码编译 vimwget https://github.com/vim/vim/archive/refs/tags/v9.1.0.tar.gz tar xzf vim-9.1.0.tar.gz cd vim-9.1.0 ./configure --with-featureshuge --enable-python3interp --prefix/usr/local make -j$(nproc) make install前提是你手头有源码包且系统有编译器。这个方法不依赖仓库但依赖“源码包本身能拷进内网”和“编译器依赖已存在”。对于只有基本系统工具且没有编译环境的机器它同样会卡住。换句话说源码编译是离线安装受限环境的最后备用选项不是首选。7. 最后的实战体会把这套流程跑过几轮之后我个人的体会是离线安装并不难难的是“你永远不知道自己漏了什么”。 rpm 和 apt 会根据当前环境已安装的包动态调整依赖解析你这个“代理下载环境”和“目标部署环境”之间的已装软件差异越大下载结果就越不可靠。所以现在我自己处理这类需求时已经养成了固定的动作习惯无论目标环境多简单先在下载机上用干净容器跑一遍yumdownloader --resolve或apt-get --download-only把完整的依赖闭环拉出来再清理掉容器。虽然多花十分钟但省掉了内网来回传包造成的几小时等待。如果你经常要处理内网机器建议直接花半天时间搭一个离线本地源后面所有机器的软件安装都会变成一条命令的事。还有个容易被忽略的点每次离线安装完把当时的系统版本、架构、下载命令、最终安装的包列表记一下。两个月后你会感谢这份记录的——那时候肯定已经忘了当初到底用了哪个 CentOS 小版本的包。
返回列表