Skip to content

软件安装

Linux 上装软件,选错安装方式会埋下各种麻烦:用包管理器装了旧版本,业务需要新特性只能卸了重来;源码编译装完依赖关系一团乱,升级时搞不清哪些文件要换;二进制包部署完忘了写 systemd unit,机器重启服务不起来。所以先搞清楚几种安装方式各自适合什么场景,再动手——这比纠结具体命令重要得多。

包管理器(yum/dnf/apt)解决的是"自动处理依赖、安全更新";源码编译解决的是"特定版本和编译选项";二进制包解决的是"快速部署、版本切换灵活"。三种方式各有取舍,不是越复杂越好,看场景选。

一、包格式和包管理器

两大发行版系列的包格式和工具要分清:

系列包格式底层工具高层工具
RHEL 系rpmrpmyum(RHEL 7)/ dnf(RHEL 8+)
Debian 系debdpkgapt

高层工具(yum/dnf/apt)在底层工具(rpm/dpkg)之上,多了自动处理依赖和连远程仓库的能力。日常装软件优先用高层工具——它们会自动把依赖一起装上,而底层工具(比如 rpm -i)不会自动装依赖,经常报"依赖缺失"。记住这个分工就够了。

查看已安装的包:

bash
rpm -qa | grep nginx            # RHEL 系
dpkg -l | grep nginx            # Debian 系

排查时一个特别有用的技巧——查某个文件属于哪个包:

bash
rpm -qf /usr/sbin/nginx         # RHEL 系
dpkg -S /usr/sbin/nginx         # Debian 系

服务器上看到一个陌生命令或者配置文件,想知道它是哪个软件装的、能不能卸,用这个命令查比靠路径瞎猜可靠得多。

二、yum 和 dnf

RHEL 8+ 用 dnf 替代了 yum,命令基本兼容,会一个就会另一个:

bash
yum install nginx -y
yum remove nginx -y
yum update nginx -y
yum list installed
yum info nginx

查看和更新仓库信息:

bash
yum repolist              # 列出已启用的仓库
yum makecache             # 更新仓库元数据缓存

只下载包不安装(适合离线环境,内网机器装软件的常见需求):

bash
yum install --downloadonly --downloaddir=/tmp/pkgs nginx

内网环境没法直连外网仓库的时候,这个命令比你自己到处找 rpm 下载链接省事多了——在有网的机器上把包和依赖全下下来,再拷到内网机器装。

三、apt

Ubuntu/Debian 用 apt:

bash
apt update                 # 更新包列表(类似 yum makecache)
apt install nginx -y
apt remove nginx -y        # 卸载包但保留配置文件
apt purge nginx -y         # 卸载包同时删掉配置文件
apt list --installed
apt show nginx

removepurge 的区别要记住:remove 只删程序不删配置,下次重装还能用之前的配置;purge 连配置一起清干净。排查"重装之后还是老配置生效"这种问题,多半是之前 remove 没清配置,得用 purge

只下载包:

bash
apt download nginx

四、rpm 和 dpkg

需要装本地包文件、或者连不上仓库的时候,才直接用底层工具:

bash
rpm -ivh package.rpm       # 安装本地 rpm(不自动解决依赖)
rpm -Uvh package.rpm       # 升级
rpm -ql nginx              # 列出这个包装了哪些文件
rpm -qi nginx              # 查看包的详细信息
bash
dpkg -i package.deb        # 安装本地 deb(可能报依赖缺失)
apt -f install             # 修复依赖问题(dpkg -i 之后经常要跑这个)

rpm -qldpkg -L 这类"列出包装了哪些文件"的命令很实用——想知道某个包装的配置文件在哪、可执行文件在哪,直接列出来看,比满世界找快。

五、仓库配置

仓库就是软件包的来源。RHEL 系的仓库配置在 /etc/yum.repos.d/ 目录下,Debian/Ubuntu 在 /etc/apt/sources.list/etc/apt/sources.list.d/

改仓库配置前一定要备份原文件:

bash
cp /etc/yum.repos.d/CentOS-Base.repo{,.bak}
cp /etc/apt/sources.list{,.bak}

{,.bak} 是 Shell 的大括号展开,生成 .bak 后缀的备份。改坏了能立刻还原,不然仓库配错 yum/apt 直接不能用,软件装不上机器就废一半。

多个第三方仓库同时启用时,容易出版本冲突——同一个包可能有好几个来源,装出来版本不对。排查的时候先确认包实际来自哪个 repo:

bash
yum info package-name             # RHEL 系,看 From 仓库
apt-cache policy package-name     # Debian 系,看 candidate 来自哪个源

六、源码编译

什么情况下才需要源码编译?仓库里没有你要的版本,或者需要特定编译选项(比如自定义 Nginx 模块)。绝大多数情况用包管理器就够了,别为了"最新版"就动不动源码编译,维护成本很高。

典型流程:

bash
tar xf app.tar.gz
cd app
./configure --prefix=/usr/local/app   # 检查依赖,生成 Makefile
make                                   # 编译
make install                           # 安装到 --prefix 指定的目录

编译前要装开发工具链:

bash
yum groupinstall "Development Tools" -y    # RHEL 系
apt install build-essential -y             # Debian 系

源码编译最大的缺点是:包管理器不知道它的存在——yum list 看不到它,卸载要靠 make uninstall(如果 Makefile 支持的话),升级要自己重新编译,依赖冲突没法被自动检测。所以源码编译的东西,目录规划要规范:统一放 /usr/local/软件名-版本/,再用软链接管理当前版本,日后维护会方便很多。不然时间一长,系统里散落一堆自己编译的东西,谁也理不清。

七、二进制包部署

很多现代服务(Go、Rust 写的工具、各种云原生组件比如 Prometheus、node_exporter)以预编译的二进制压缩包形式发布,部署方式就是直接解压:

bash
tar xf app-1.2.3-linux-amd64.tar.gz -C /opt/
ln -sfn /opt/app-1.2.3 /opt/app

这种部署方式下,目录规划有个通用惯例:

路径放什么
/opt/app-版本各版本的程序文件
/opt/app软链接,指向当前在用的版本
/etc/app配置文件
/var/log/app日志文件
/var/lib/app持久化数据

二进制部署最大的优势是回滚极快——把 /opt/app 软链接指回旧版本目录,重启服务就完成回滚了,几秒钟的事。缺点也明显:systemd unit、日志轮转、专用用户创建、升级流程都得自己写,不像包管理器装的东西这些都已经集成好了。

八、安装后确认

装完不等于能用,至少确认这几件事:

bash
which nginx                      # 确认命令在 PATH 里能找到
nginx -v                         # 确认版本对不对
systemctl status nginx           # 确认服务状态

机器上如果装过多个版本,which 查出来的路径可能跟你预期的不一样。比如同时有包管理器装的 nginx(在 /usr/sbin/nginx)和二进制部署的 nginx(在 /opt/nginx/sbin/nginx),which nginx 取决于 PATH 里哪个目录在前。排查"为什么改了配置不生效"这种问题,先 which 确认实际跑的是哪一个,别对着一个版本的配置改半天,结果系统跑的是另一个版本。