作为一名Linux系统管理员,软件包管理是最基础也是最重要的技能之一。不同于Windows系统的傻瓜式安装,Linux提供了多种软件管理方式,每种方式都有其适用场景和优缺点。
在Linux世界中,不同的发行版使用不同的包管理系统,这主要源于Linux的开放性和多样性。Red Hat系列(如CentOS、RHEL、Fedora)使用RPM包管理系统,而Debian系列(如Ubuntu、Debian)则使用DEB包管理系统。此外,还有通用的源码包和绿色软件等形式。
掌握多种软件管理方式的好处在于:
绿色软件是最简单的软件形式,通常是一个压缩包,解压后即可运行,不需要安装过程。这类软件的特点是:
典型使用场景:
实际操作示例:
bash复制# 下载Firefox绿色版
wget https://download.mozilla.org/?product=firefox-latest&os=linux64&lang=en-US -O firefox.tar.bz2
# 解压
tar xjf firefox.tar.bz2
# 运行
cd firefox
./firefox
注意事项:
源码包是软件的原始代码形式,需要编译后才能使用。这是最灵活的安装方式,适合:
典型编译安装流程:
bash复制# 下载源码包
wget http://nginx.org/download/nginx-1.25.3.tar.gz
# 解压
tar zxf nginx-1.25.3.tar.gz
cd nginx-1.25.3
# 配置编译选项
./configure --prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_v2_module
# 编译并安装
make
sudo make install
编译安装的优缺点:
优点:
缺点:
RPM(Red Hat Package Manager)是Red Hat系列发行版的包格式,具有以下特点:
RPM包命名规则示例:
code复制httpd-2.4.57-1.el9.x86_64.rpm
DEB是Debian系列发行版(如Ubuntu)使用的包格式,使用dpkg和apt工具管理。虽然本文主要介绍RPM系列,但了解DEB包的基本概念也很重要:
安装RPM包的基本命令:
bash复制# 基本安装(显示详细信息)
sudo rpm -ivh package.rpm
# 升级安装
sudo rpm -Uvh package.rpm
# 重新安装(修复损坏的安装)
sudo rpm -ivh --replacepkgs package.rpm
强制安装选项(慎用):
bash复制# 忽略依赖安装(可能导致软件无法运行)
sudo rpm -ivh --nodeps package.rpm
# 忽略文件冲突(可能覆盖重要文件)
sudo rpm -ivh --replacefiles package.rpm
卸载软件:
bash复制# 正常卸载
sudo rpm -e package-name
# 强制卸载(可能破坏系统稳定性)
sudo rpm -e --nodeps package-name
RPM提供了强大的查询功能,可以获取软件包的各类信息:
基本查询:
bash复制# 列出所有已安装的包
rpm -qa
# 查询特定包是否安装
rpm -q httpd
# 获取包的详细信息
rpm -qi httpd
文件相关查询:
bash复制# 查看文件属于哪个包
rpm -qf /usr/sbin/httpd
# 列出包安装的所有文件
rpm -ql httpd
# 列出包的配置文件
rpm -qc httpd
# 列出包的文档文件
rpm -qd httpd
验证包完整性:
bash复制# 验证包文件是否被修改
rpm -V httpd
# 检查RPM包签名
rpm -Kv package.rpm
查看安装/卸载脚本:
bash复制# 查看预安装脚本
rpm -q --scripts package-name | grep preinstall
# 查看卸载脚本
rpm -q --scripts package-name | grep postuninstall
提取RPM包中的文件:
bash复制# 提取单个文件
rpm2cpio package.rpm | cpio -idmv ./path/to/file
# 提取所有文件
rpm2cpio package.rpm | cpio -idmv
依赖问题是RPM包管理中最常见的挑战之一。理解依赖关系对系统管理员至关重要。
查看包的依赖关系:
bash复制# 查看包依赖哪些其他包
rpm -qR httpd
# 查看哪些包依赖当前包
rpm -q --whatrequires httpd
当遇到依赖问题时,可以尝试以下方法:
bash复制sudo dnf install package.rpm
bash复制# 首先查看缺少什么依赖
sudo rpm -ivh package.rpm
# 然后使用yum/dnf下载依赖
sudo dnf download dependency-package
bash复制# 将所有相关RPM包放入一个目录
mkdir /tmp/local-repo
cp *.rpm /tmp/local-repo/
# 创建仓库元数据
createrepo /tmp/local-repo
# 临时使用本地仓库
sudo dnf --disablerepo=* --enablerepo=local-repo install package
基本安装命令:
bash复制# 安装软件
sudo dnf install nginx
# 安装指定版本
sudo dnf install nginx-1.20.1
# 安装本地RPM包(自动解决依赖)
sudo dnf install ./package.rpm
更新操作:
bash复制# 检查可用更新
sudo dnf check-update
# 更新所有软件
sudo dnf update
# 更新指定软件
sudo dnf update nginx
# 系统升级(跨版本)
sudo dnf upgrade
卸载软件:
bash复制# 卸载软件
sudo dnf remove nginx
# 删除无用依赖
sudo dnf autoremove
# 清理缓存
sudo dnf clean all
软件列表查询:
bash复制# 列出所有已安装软件
dnf list installed
# 列出可用更新
dnf list updates
# 列出仓库中所有软件
dnf list available
搜索功能:
bash复制# 按名称搜索
dnf search python3
# 查找提供特定文件的包
dnf provides /usr/bin/python3
# 查看软件详细信息
dnf info nginx
创建本地仓库的完整流程:
bash复制# 创建挂载点
sudo mkdir /mnt/rhel9
# 挂载ISO
sudo mount -o loop RHEL9.iso /mnt/rhel9
# 设置自动挂载
echo "/dev/cdrom /mnt/rhel9 iso9660 defaults,ro 0 0" | sudo tee -a /etc/fstab
bash复制sudo vi /etc/yum.repos.d/local.repo
[BaseOS]
name=Local BaseOS
baseurl=file:///mnt/rhel9/BaseOS
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
[AppStream]
name=Local AppStream
baseurl=file:///mnt/rhel9/AppStream
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
bash复制# 清除缓存
sudo dnf clean all
# 重建缓存
sudo dnf makecache
# 列出可用仓库
sudo dnf repolist
EPEL仓库配置:
bash复制sudo dnf install epel-release
或者手动配置:
bash复制sudo vi /etc/yum.repos.d/epel.repo
[epel]
name=EPEL
baseurl=https://mirrors.aliyun.com/epel/$releasever/Everything/$basearch/
enabled=1
gpgcheck=1
gpgkey=https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-$releasever
Docker CE仓库配置:
bash复制sudo vi /etc/yum.repos.d/docker-ce.repo
[docker-ce-stable]
name=Docker CE Stable
baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/stable
enabled=1
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
当多个仓库提供同一个软件时,可以通过优先级控制使用哪个仓库:
bash复制sudo dnf install yum-plugin-priorities
sudo vi /etc/yum.repos.d/epel.repo
[epel]
...
priority=10
DNF会记录所有操作,便于回滚:
bash复制# 查看历史
sudo dnf history
# 查看某次操作的详细信息
sudo dnf history info 6
# 撤销操作
sudo dnf history undo 6
# 重做操作
sudo dnf history redo 6
软件组是一组相关软件的集合:
bash复制# 列出可用软件组
sudo dnf group list
# 查看软件组内容
sudo dnf group info "Development Tools"
# 安装软件组
sudo dnf group install "Development Tools"
模块是RHEL8引入的新概念:
bash复制# 列出可用模块
sudo dnf module list
# 启用模块
sudo dnf module enable postgresql:12
# 安装模块
sudo dnf module install postgresql:12
典型依赖错误及解决方案:
code复制Error: Package: nginx-1.20.1-1.el7.x86_64 (epel)
Requires: libcrypto.so.1.1()(64bit)
解决方案:
bash复制sudo dnf install openssl11-libs
code复制file /usr/bin/python from install of python2-2.7.18-1.el7.x86_64 conflicts with file from package python-3.6.8-1.el7.x86_64
解决方案:
bash复制# 使用alternatives系统
sudo alternatives --config python
# 或者安装特定版本的包
sudo dnf install python3-3.6.8
常见仓库错误:
code复制Could not resolve host: mirror.centos.org
解决方案:
bash复制# 检查网络连接
ping mirror.centos.org
# 尝试其他镜像
sudo sed -i 's/mirror.centos.org/mirrors.aliyun.com/g' /etc/yum.repos.d/*.repo
code复制Public key for package.rpm is not installed
解决方案:
bash复制# 导入密钥
sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
# 或者临时禁用验证
sudo dnf install --nogpgcheck package.rpm
bash复制sudo dnf install yum-plugin-fastestmirror
bash复制# 在/etc/dnf/dnf.conf中添加
max_parallel_downloads=10
bash复制# 避免每次更新元数据
keepcache=1
bash复制sudo dnf --cacheonly install package
bash复制#!/bin/bash
# 批量安装列表中的软件
PKGLIST="nginx mysql-server php-fpm"
for pkg in $PKGLIST; do
if ! rpm -q $pkg &>/dev/null; then
echo "Installing $pkg..."
sudo dnf install -y $pkg
else
echo "$pkg is already installed"
fi
done
bash复制#!/bin/bash
# 分析包的依赖树
if [ -z "$1" ]; then
echo "Usage: $0 <package>"
exit 1
fi
echo "Dependency tree for $1:"
rpm -q --requires $1 | while read dep; do
echo "|- $dep"
rpm -q --whatprovides "$dep" | grep -v "^no package" | while read provider; do
echo "| |- $provider"
done
done
bash复制#!/bin/bash
# 清理无用仓库和缓存
echo "Cleaning DNF cache..."
sudo dnf clean all
echo "Removing disabled repos..."
find /etc/yum.repos.d/ -type f -name "*.repo" -exec grep -l "enabled=0" {} \; | while read repo; do
echo "Removing $repo"
sudo rm -f "$repo"
done
echo "Checking for duplicate repos..."
grep -h "^\[" /etc/yum.repos.d/*.repo | sort | uniq -d
bash复制# 检查RPM数据库状态
sudo rpmdb -v
# 重建RPM数据库(解决性能问题)
sudo rpmdb --rebuilddb
bash复制# 查看详细的事务时间
sudo time dnf install nginx
bash复制# 创建文件索引(加快rpm -qf查询)
sudo rpm --initdb
在实际工作中,我发现很多问题都源于对软件包管理机制的不够了解。比如有一次,一个同事强制安装了带有--nodeps选项的包,结果导致系统出现难以排查的依赖问题。从那以后,我养成了几个好习惯:
dnf repoquery --requires查看它的依赖关系rpm -Va验证系统文件的完整性另外,在处理生产环境时,我建议先在测试环境验证任何软件变更。曾经有一次,一个看似简单的glibc更新导致了整个系统的兼容性问题,幸好我们是在测试环境发现的。