ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

rpm、yum、npm关系详解:系统包管理与Node依赖管理核心区别

rpm、yum、npm关系详解:系统包管理与Node依赖管理核心区别 先说一个常见的场景。新接一台 CentOS 7 服务器手头有个 nginx 的 rpm 包直接rpm -ivh装上结果提示缺依赖一脸懵。打开网上教程又是让用yum install又是让npm install你心里肯定冒出一个问题rpm、yum、npm 到底有什么区别这仨名字长得像实际上根本不是一回事。我最早被这三者绕晕是在一次自己折腾服务器的时候。后来在运维和前后端项目里混得久了才算把它们的边界彻底理清楚。一句话先说结论rpm 是红帽系 Linux 系统里的一种软件包格式yum 是基于 rpm 之上、专门帮你解决依赖的包管理器而 npm 是 Node.js 生态的依赖管理器它装的是前端或 Node 项目的库跟系统软件包完全不沾边。这篇文章就是把这套东西掰开揉碎讲清楚顺便把三者的高频常用命令、还有我踩过的坑都整理出来。适合刚入门 Linux 的开发者、需要维护服务器的运维同学以及前端项目里被 npm 各种报错绕晕的朋友。1. 先把概念理清楚rpm、yum、npm 到底各自干什么1.1 rpm系统的“安装包”而不是“安装工具”很多人误以为 rpm 是一个装软件的命令其实 rpm 更准确的定位是一种软件包格式后缀是.rpm同时配套一条也叫 rpm 的命令来对它进行操作。红帽系的系统比如 RHEL、CentOS、Rocky Linux、Fedora以及国内的银河麒麟、统信 UOS 这类基于或兼容红帽生态的系统沿用的都是这套 rpm 格式。rpm 包里面装的是什么本质上是一个已经编译好的程序加上配置文件、启动脚本、文档这些零零碎碎的东西打包到一起安装时按清单把文件放到系统对应目录然后把安装记录写进本机 rpm 数据库。这个数据库一般在/var/lib/rpm和/var/lib/dpkg里头查询、卸载、校验全靠它。关键点在于rpm 本身只负责“安装、卸载、查询、校验”这些动作它不负责拉取软件和设备之间的依赖。什么叫依赖比如你要装 nginxnginx 运行依赖一个叫 openssl 的库如果系统里没有这个库rpm 会干巴巴地告诉你“需要 libssl.so.1.1 但没有装”然后就不动了。你得自己去找到这个库的 rpm 包再来一轮安装。如果那个 rpm 又依赖别的包你就陷入了经典的依赖地狱。所以rpm 命令适合的场景是软件包已经下载到本地、依赖关系清晰、或者你需要精细控制安装过程的离线场景。1.2 yum替你操心依赖的包管理器yum 全称 Yellowdog Updater Modified它的出现就是为了解决 rpm 依赖地狱。yum 本身不直接打包软件它也是调用 rpm 来装包但它在 rpm 外面包了一层“自动解析依赖”的机制。具体怎么实现yum 会从配置好的软件仓库repository里拉取软件包元数据这些元数据描述了每个包依赖什么、提供什么。它把这些信息放到本地一个缓存里你要装 nginxyum 通过元数据自动算出 nginx 需要哪些依赖库然后把这些依赖包和 nginx 一起从仓库里拉下来逐个交给 rpm 安装。你只敲一个命令后面一长串依赖它全包了。yum 的仓库配置在/etc/yum.repos.d/目录下.repo后缀的文件。比如 CentOS 7 默认有 BaseOS、AppStream 等仓库你可以换成阿里源、腾讯源、清华源也可以自己做一个本地 yum 源指向挂载的光盘镜像。到了 CentOS 8 / Rocky 8 之后的版本yum 被 dnf 取代了dnf 是 yum 的下一代实现性能更好但命令用法基本一致很多系统里你依然能直接敲yum系统会转给 dnf。所以后面我讲到 yum 命令你可以在新系统里直接换成 dnf逻辑不变。一句话yum/dnf 是“系统级包管理器”负责给整个操作系统安装、更新、卸载软件并且自动解决依赖。1.3 npmNode.js 世界的依赖管家跟系统包不是同一个赛道npm 全称 Node Package Manager是随 Node.js 一起安装的包管理器。它管理的对象是 JavaScript 项目里的第三方库和模块比如前端框架 Vue、React后端框架 Express工具库 axios、lodash构建工具 webpack、vite 等等。为什么 npm 经常被和 yum 放在一起说因为使用逻辑上有相似之处都需要一个远程仓库registry都要通过一个配置文件来声明依赖都能自动处理依赖关系。npm 的仓库默认地址是https://registry.npmjs.org/国内一般会用镜像源如https://registry.npmmirror.com/来加速也就是常说的“npm 国内镜像源”。依赖声明写入项目根目录的package.json文件实际安装的文件放在node_modules目录。注意一个容易混淆的点npm 装的是 Node 模块是给 JavaScript 项目用的不是给操作系统用的。你不能用npm install nginx来装一个系统软件也不能用yum install axios来给 Node 项目装依赖。这俩生态完全隔离一个是系统级一个是项目级。1.4 一句话对比表格工具本质适用范围依赖处理安装对象rpm软件包格式 底层安装工具红帽系 Linux 本地包不自动解决.rpm安装包yum / dnf系统级包管理器红帽系 Linux 系统软件自动从仓库拉取依赖仓库里的软件包npmNode.js 包管理器JavaScript / Node.js 项目自动从 registry 拉取npm 包 / 模块这个表格建议收藏想不明白时拿出来看一眼。2. rpm 命令实战低频但牵一发动全身2.1 查询快速判断“装了没”“文件归谁”rpm 用的最多的是查询而不是安装。我日常排查服务器问题时第一件事就是确认某个软件到底装没装、装的是什么版本、有哪些文件、这些文件属于谁。# 查询某个软件包是否安装 rpm -q nginx # 列出所有已安装且名字包含 nginx 的包 rpm -qa | grep nginx # 查看指定包的详细信息包括版本、发布时间、安装时间 rpm -qi nginx # 列出这个包安装后都释放了哪些文件 rpm -ql nginx # 反查系统里某个文件 /usr/bin/xx 是哪个 rpm 包安装出来的 rpm -qf /usr/bin/nginxrpm -qa | grep是我在捣鼓环境时敲得最多的命令。比如记不清机器上到底有没有装过 openssl-devel一句rpm -qa | grep openssl直接看输出结果。rpm -qf也很实用当你不知道/etc/nginx/nginx.conf这个文件是谁生成的用它反查一下就能定位到来源。2.2 安装rpm -ivh 和它的两个危险开关安装的完整命令是rpm -ivh package.rpm参数拆解-i是 install-v是显示详细信息-h用#号显示安装进度。平时我习惯连写成-ivh如果只想要安静安装也可以只写-i但看不到进度等半天不知道卡没卡所以还是建议加上-vh。如果这个包之前装过旧版本可以用升级方式rpm -Uvh package.rpm-U代表 upgrade如果有旧包会先卸载旧包再装新包没有旧包则直接安装。-Fvh则不同-F是 freshen只在有旧包的时候才升级没有旧包就跳过这在批量更新已装包时比较有用。这里必须重点说两个危险参数--nodeps和--force。当 rpm 报缺失依赖时很多人第一反应是加--nodeps忽略依赖强装上去然后程序运行时报段错误或缺少动态库。我的建议是能不用就不要用。特别在生产环境缺依赖说明系统里确实没有对应库强装等于埋雷。但也有例外比如你的系统里已经存在某个库的更新版本rpm 因为把版本限制死而误判缺失这时候加--nodeps强装是合理的。--force通常配合--nodeps一起出现作用是强制覆盖已安装的文件我一般只在打包自己的安装包、明确知道要覆盖哪些文件时才用它。2.3 卸载与校验清干净和不被动过手脚卸载命令rpm -e nginx-e是 erase。如果卸载时报“某个依赖这个包”而无法删除说明系统里还有其他软件在依赖它。这时候不要慌先像上面那样用rpm -q看看到底是谁在依赖确认无误后再考虑是否删除。另有一个场景比较特殊某些服务被攻击或误操作后配置文件被改动你可能需要快速校验。rpm 提供了校验功能rpm -V nginx-V会拿当前系统文件跟 rpm 数据库里记录的原始信息比对。如果输出结果为空说明文件都对。若有输出每一行开头的字母代表不同的变更类型比如S表示文件大小变了M表示权限变了5表示 MD5 校验不通过。检查被改动的文件是否被篡改时这个命令就是利器。2.4 实战场景离线安装 openssh-10.3 的 rpm 包最近网上很多人搜 openssh-10.3 rpm 包下载这个场景特别典型线上服务器扫出来 openssh 有安全漏洞需要升级但默认 yum 源里的 openssh 版本很旧你只能去外部渠道下载新版本 rpm 包然后在内网离线安装。下载到本地后我的习惯是先做一轮依赖检查rpm -qpR openssh-xxx-10.3.rpm-q是查询-p是对尚未安装的 rpm 包文件操作-R是列出依赖。这条命令会告诉你这个包要求哪些依赖库。接下来逐个确认系统里有没有rpm -q openssl-libs最后再rpm -Uvh openssh-xxx-10.3.rpm安装。如果升级 openssh-server 这种敏感服务安装前千万要确认 sshd 的配置备份好了否则一旦重启失败你连不上服务器就只能去机房或带外管理口操作了。3. yum/dnf 命令实战日常装系统的真正主角3.1 安装、卸载、更新全套命令yum 的命令规则很好记核心就几个动作。# 搜索软件包 yum search nginx # 查看软件仓库列表 yum repolist # 查看某个包的详细信息 yum info nginx # 安装 yum install -y nginx # 卸载 yum remove nginx # 更新指定包 yum update nginx # 更新所有可更新包 yum update -y # 只下载不安装 yum install --downloadonly --downloaddir/opt/packages nginx # 清理缓存 yum clean all # 列出已安装的包 yum list installed-y参数的意思是全自动回答 yes所有交互提示都跳过。我建议脚本里和交互式命令行里都加上不然半夜远程装包一个“Is this ok [y/N]:”卡住你睡着了它等着很崩溃。yum search适合你只知道大概名字、不确定准确包名的时候。比如你想装图形界面的文本编辑器敲yum search gedit就把所有包名和描述里带 gedit 的包都列出来。yum info可以看版本、大小、仓库来源装之前瞄一眼可以避免装错包。3.2 更新排除内核与 openssh 这类敏感包生产环境最怕什么最怕手贱yum update -y把所有包全更新了结果内核升级后驱动不兼容或者 openssl 版本变化导致某些服务起不来。更新策略我的经验是默认不更新内核只更新业务相关的安全补丁且更新前备份配置。排除内核更新用这个yum update -y --excludekernel*--exclude是排除指定通配符的包这样 yum 在更新时就会跳过所有名字以 kernel 开头的包。同理如果想固定 openssh 不升级写--excludeopenssh*。还有yum update和yum upgrade的区别。老版本 yum 里二者行为基本一致都是更新所有可更新包在新版 dnf 里upgrade是默认的更新行为update则是upgrade的别名。习惯上生产环境建议用yum update --excludekernel*别让它轻易动内核。升级完 openssh 那类网络服务一定要记住重启 sshd 之前先检查配置sshd -t如果这个检查都没过千万别重启服务否则 ssh 会直接断开而你还没法通过 ssh 重新连上——这就是经典的“自己把自己锁在门外”事故。3.3 把 yum 源换成阿里源精确到版本的坑CentOS 7 时代最常见的操作是换阿里源。核心步骤是备份系统自带的.repo文件然后下载阿里的官方仓库文件。# 备份 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak # 下载阿里源CentOS 7 为例 curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo # 清理缓存并重新生成 yum clean all yum makecache这里有几个坑。第一CentOS 8 及以后的版本系统默认仓库文件多了 AppStream、PowerTools 等阿里源也有对应的Centos-8.repo注意区分下载。第二CentOS 7、CentOS 8、CentOS 9 的源文件 URL 不同不要拿 7 的源文件配置到 9 上。第三如果你用的是 redhat 6.5 这种老版本或者银河麒麟这类国产系统网络上的通用源不一定兼容最好的做法是优先用系统自带的源或者官方源镜像。换完源后做一次yum repolist确认仓库生效看到输出里有可用的仓库包数量再开始装东西。CentOS 7 已经 EOL 之后网上很多源也在陆续失效如果你手头还有 7 在跑建议尽快找替代方案或把源切到 vault 归档目录不然就会遇到“errors during downloading metadata”这种下载元数据失败的问题。3.4 本地 yum 源搭建离线环境全靠它内网环境里没有外网又要给一批服务器装软件最快的方法就是用系统镜像盘做本地 yum 源。这也是 CentOS 7 本地 yum 源搭建、Linux 配置本地 yum 源实验目的里最常讨论的操作。先挂载镜像mkdir -p /mnt/cdrom mount /dev/cdrom /mnt/cdrom然后创建本地仓库文件vi /etc/yum.repos.d/local.repo内容如下[local] nameLocal Repository baseurlfile:///mnt/cdrom enabled1 gpgcheck0保存后执行yum clean all yum makecache yum repolist如果repolist里能看到 local 仓库说明本地源生效可以开始离线装包了。这里有几个容易踩的细节。第一CentOS 8 / Rocky 8 的光盘镜像在挂载后软件包实际分布在/mnt/cdrom/BaseOS和/mnt/cdrom/AppStream两个目录直接写baseurlfile:///mnt/cdrom是装不上的要分别建两个仓库[BaseOS] nameBaseOS baseurlfile:///mnt/cdrom/BaseOS enabled1 gpgcheck0 [AppStream] nameAppStream baseurlfile:///mnt/cdrom/AppStream enabled1 gpgcheck0第二实验做完别忘了卸载镜像有的同学搞完直接重启结果服务器卡在“No bootable device”因为光盘还插在光驱里且引导顺序靠前。第三gpgcheck0表示跳过 GPG 密钥校验离线环境一般没问题但如果包来源不明建议保留gpgcheck1并配置gpgkey。额外提醒本地源的包版本一般偏旧因为镜像盘的软件包在发行时就已经固定了之后的安全更新不会包含在内。所以本地源适合解决“能不能装上”的问题升级安全补丁还是得走外网源。3.5 下载 rpm 包到本机批量分发有时候你不是要在本机装而是要一次性给多台服务器装同一批软件。这时候直接把 rpm 包下载下来拷到别的机器上再用 rpm 安装比每台机器都走一次网络源快得多。# 方法一yum 的 downloadonly 插件 yum install --downloadonly --downloaddir/opt/packages nginx # 方法二yumdownloader 工具 yum install -y yum-utils yumdownloader --resolve --destdir/opt/packages nginx重点说下yumdownloader --resolve--resolve意思是把依赖包也一起下载下来。只写yumdownloader nginx的话它只会下载 nginx 本体依赖库还得另想办法。这个细节非常关键离线场景下如果依赖不全到对方机器上一样会报缺依赖。把/opt/packages目录里的 rpm 全部安装的批量命令是rpm -Uvh /opt/packages/*.rpm注意rpm -Uvh处理同目录多个包时会先统一分析依赖关系再逐个安装所以即使包之间互相依赖也能自动判断顺序比手动逐个敲要稳。4. npm 命令实战前端和后端 Node 项目的日常4.1 初始化、安装、卸载、查看一条龙npm 的核心工作对象是package.json。进入一个项目目录第一次执行npm init会让你填写项目名、版本、入口文件等一堆信息嫌麻烦就直接npm init -y-y表示使用默认值快速生成package.json后续再手动改里面的字段。安装依赖是最常用的操作# 安装项目依赖并写入 dependencies npm install axios # 简写形式 npm i axios # 安装开发依赖写入 devDependencies npm install -D typescript # 全局安装 npm install -g nodemon # 安装 package.json 里所有依赖 npm installdependencies是项目运行时需要的依赖比如 Express、axiosdevDependencies是开发和构建阶段需要、但生产环境可以不要的工具比如 typescript、webpack、eslint。这个区分除了规范意义也直接影响npm install --production的行为——生产环境只装dependencies不装开发依赖能省下不少空间和装包时间。卸载npm uninstall axios npm uninstall -g nodemon查看已安装的包npm list npm list --depth0npm list --depth0只显示项目直接依赖不列间接依赖输出很清爽。查看某个包的最新版本和相关信息npm view axios npm view axios versionnpm view axios version会直接输出云端最新版本号比如 1.7.2方便你判断是否要升级。4.2 换镜像源提速npm 默认仓库在国外国内网络经常慢得离谱卡在npm ERR! network或者等半天进度条不动。更有效的手段是配置国内镜像源。现在主流推荐的是淘宝 npm 镜像# 查看当前镜像源 npm config get registry # 设置为淘宝镜像源 npm config set registry https://registry.npmmirror.com/ # 设置回官方源 npm config set registry https://registry.npmjs.org/除了全局配置也可以在项目根目录新建.npmrc文件写入registryhttps://registry.npmmirror.com/这种方式只对当前项目生效不会影响其他项目我在公司项目里更推荐这种避免把开发者机器上的全局源改成乱七八糟的地址。如果你不想改配置也可以临时指定源npm install --registryhttps://registry.npmmirror.com/缺点是每次都要打长参数适合偶尔用一次的场景。4.3 Windows 下 npm 的两个经典报错Windows 系统下 npm 的报错特别经典一个是“npm : 无法加载文件 C:\Program Files\nodejs\npm.ps1因为在此系统上禁止运行脚本”另一个是“npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称”。第一个报错是因为 PowerShell 的执行策略默认是 Restricted禁止运行.ps1脚本而 npm 在 PowerShell 里执行时走的是 npm.ps1。解决办法是用管理员身份打开 PowerShell执行Set-ExecutionPolicy RemoteSigned执行后选Y确认。RemoteSigned的意思是本地脚本可以运行从网上下载的脚本必须经过签名才能运行兼顾安全和便利。如果不想修改全局策略也有另一种方法在cmd命令行里跑 npm 命令因为 cmd 不检查 PowerShell 执行策略完全绕开这个限制。第二个报错“无法识别为 cmdlet”通常是 Node.js 没装好或者环境变量PATH里没有 Node.js 的安装路径。先确认安装目录然后手动把 Node.js 的安装路径比如C:\Program Files\nodejs\加进系统环境变量Path里。添加后必须重新打开一个命令行窗口环境变量才会生效这是新手最容易忽略的一点。还有一个小问题是 npm 安装时频繁输出的 deprecation 警告比如npm warn deprecated node-domexception1.0.0: use your platforms native DOMException instead看到这种npm warn不要太担心它提示的是某个间接依赖的包已被作者标记作废旧版本可能有安全隐患或功能缺陷。多数情况下这只是旧的传递依赖在提醒你该升级了如果项目能正常构建可以暂时不管。但如果警告指向的是重要依赖建议用npm outdated看一下有哪些包可以更新然后针对性升级。4.4 发布 npm 包的基本流程自己写的工具库想发布到 npm 仓库供团队使用流程不复杂。# 1. 首次登录 npm adduser # 2. 已有账号则登录 npm login # 3. 修改版本号patch 是补丁版本minor 是小版本major 是大版本 npm version patch # 4. 发布 npm publishnpm version patch会直接把package.json里的版本号从 1.0.0 改成 1.0.1并提交一个 git tag。minor把 1.0.1 变成 1.1.0major变成 2.0.0。发布之前最好确认package.json里的name在 npm 仓库里没有被占用以及files字段定义好了要发布哪些文件不然把自己项目里的源码、测试文件、配置文件全发出去了别人下载后看到一堆杂乱文件体验很差。我在files里通常只放发布必需的dist目录和 README。5. 三者界限与常见问题速查5.1 什么时候该用哪个从实际场景出发第 1 节的表格是从技术角度对比这里我换个角度从实际场景出发讲怎么选。如果你是系统管理员要在 CentOS/Rocky 上装一个系统服务比如 Nginx、MySQL、Docker优先用yum。仓库里有现成包依赖自动处理卸载也干净。只有在离线环境、或软件仓库里没有你需要的特定版本、或者你自己打包了 rpm 需要测试时才退到rpm层面操作。如果你是前端或 Node 后端开发者要给项目装 JS 库就必须用npm并且只在项目里用npm install管理依赖不要试着用yum给 Node 项目装模块。同理系统管理员也不要看到npm就以为是安装工具它能装的东西跟系统毫无关系。唯一会交叉的场景是你需要在系统里安装 Node.js 本身这时候用yum install nodejs或下载官方二进制包装好之后npm只是 Node.js 自带的一个命令。判断方法很简单系统级程序用 yum/rpm项目级 JS 库用 npm。分清这个基本就不会混了。5.2 高频报错与排查方法汇总报错信息 / 现象原因处理办法提示“没找到 rpm 命令”系统不是红帽系比如 Ubuntu/Debian 用的是 dpkg/apt改用 apt 家族命令或确认最初安装系统时是否最小化到没装 rpmyum install提示“errors during downloading metadata”yum 仓库地址失效、网络不通、源配置错误yum clean all后检查/etc/yum.repos.d/里的 URL 是否能访问重换可用源rpm -ivh报依赖缺失系统缺少运行库或包版本冲突用yum install代替或手动下载缺失依赖的 rpm 再装rpm -e报“需要”依赖无法卸载有其他包依赖这个包用rpm -q --whatrequires 包名查谁依赖它确认后再删npm : 无法加载...npm.ps1因为禁止运行脚本PowerShell 执行策略限制管理员身份执行Set-ExecutionPolicy RemoteSigned或在 cmd 中运行 npmnpm : 无法识别为 cmdletNode.js 未安装或 PATH 环境变量缺失安装 Node.js并把node.exe所在目录加入 PATH重启命令行npm install很慢或卡住默认源在国外访问慢切换淘宝镜像源npm config set registry https://registry.npmmirror.com/yum repolist看不到本地仓库.repo文件路径或 baseurl 写错检查/etc/yum.repos.d/文件权限和 baseurl 路径CentOS 8 注意 BaseOS 和 AppStream 分开配置这张表里每个问题都是实际踩过或帮同事排查过的。排查思路其实就是先确认“是不是网络问题、是不是配置问题、是不是权限问题”再依次排除。比如 yum 报下载元数据失败先 ping 一下源域名通不通通的话再检查 URL 是否 404还不行就清理缓存重来。别一上来就找重装系统这种终极大招。5.3 关于“Artisan 版本”的补充说明这里补充一点有时候你会发现同样都是 rpm 包有的叫.rpm有的叫.src.rpm。.rpm是编译好的二进制包直接安装就能用.src.rpm是源代码包装进去的是源码和编译脚本需要用rpmbuild重新编译成二进制包再安装。正常使用场景下我们下载的都是二进制.rpm看到.src.rpm不用下载那是给维护者用的。还有 CentOS 7 之后yum命令在很多新旧系统里还能互相兼容但在纯 dnf 系统上部分老命令像yum repolist照样能用这就导致很多人根本分不清自己在用哪个。我的建议是新系统直接养成敲dnf的习惯老系统继续用yum两者在这个层面的差异对你的实际经验积累没有影响。6. 最后再分享一点个人心得这三样工具我用了很多年最大的体会是别把它们当竞争对手它们是不同层次的东西。rpm 是单机离线安装的保底方案yum/dnf 是红帽系系统的软件入口npm 是 JavaScript 生态的依赖管家。它们之所以容易被放在一起讨论是因为命令行风格相似、时间长了大家习惯了“装软件就是用这类命令”的直觉。我在实际项目里长期保持的习惯是新装一台服务器先想清楚“这台机器有没有外网如果有优先配好 yum 源再用 yum如果没有准备好镜像盘或本地源再动工要开发 Node 项目就专心用 npm”。更新策略上一律保守生产环境不追新yum update -y --excludekernel*是我的默认动作。npm 这边则坚持用package-lock.json锁定依赖版本避免某天某依赖升级后悄悄出问题。如果这篇文章能帮你少走一次弯路那这半小时就没白折腾。实际操作中遇到问题多试试man rpm、man yum、npm help命令文档里写的永远比二手教程细。
返回列表