当前位置: 首页 > news >正文

RPM之(1)基础使用

RPM之(1)基础使用


Author: Once Day Date: 2025年5月26日

一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦…

漫漫长路,有人对你微笑过嘛…

全系列文章可参考专栏: Linux实践记录_Once-Day的博客-CSDN博客

参考文章:

  • Linux安装及管理工具(rpm和yum)_yam源-CSDN博客
  • linux下RPM工具的使用:RPM安装/查询/查看/卸载/升级软件包 - 人生的哲理 - 博客园
  • Linux软件管理-RPM工具 - 知乎
  • Linux rpm命令 | 菜鸟教程
  • rpm.org - Home

文章目录

  • RPM之(1)基础使用
        • 1. 概述
          • 1.1 背景
          • 1.2 RPM包命名格式
          • 1.3 常见RPM命令
        • 2. 实践
          • 2.1 构建RPM包
          • 2.2 安装RPM包
          • 2.3 RPM优化(压缩速度)

1. 概述
1.1 背景

RPM(Red Hat Package Manager)的发展历程可以追溯到1997年。当时Linux发行版的软件包管理比较混乱,Red Hat公司为了解决这个问题,开发了RPM包管理系统。

最初RPM是专门为Red Hat Linux设计的,但由于其优秀的特性,很快被其他Linux发行版采用。SUSE、OpenSUSE、CentOS等知名发行版都将RPM作为默认的包管理系统。

RPM的主要创新在于:

  • 引入了软件包依赖关系管理,解决了软件安装时的依赖问题。
  • 支持数字签名验证,提高了软件分发的安全性。
  • 实现了软件包数据库,方便系统管理和维护。
  • 支持软件包升级和回滚,降低了系统维护风险。

RPM的核心特性:

  • 数据库管理:维护着已安装软件的完整数据库,存储在/var/lib/rpm目录下,记录文件属性,依赖关系等信息。

  • 依赖解析:自动处理软件包之间的依赖关系,防止删除被其他包依赖的包,支持版本号限定的依赖关系。

  • 文件完整性验证:使用MD5等算法验证包完整性,支持GPG签名验证,防止软件包被篡改。

  • 软件包制作:支持从源码构建RPM包,使用spec文件描述构建过程,可以创建源码包(SRPM)。

RPM的高级特性:

  • 并行安装:支持同一软件的多个版本共存,通过不同的包名实现。

  • 事务性操作:安装过程是原子的,失败时自动回滚。

  • 脚本支持:pre/post install脚本,pre/post uninstall脚本,trigger脚本。

  • 虚拟包:提供功能而不是实际文件,用于处理替代包。

经过多年发展,RPM已经成为Linux世界的重要标准之一。目前最新的RPM 4.x版本增加了很多现代特性,比如并行安装支持、更强的依赖分析等。作为一个成熟的包管理工具,RPM为Linux系统的软件管理带来了规范化和便利性,是Linux系统管理中不可或缺的工具。

1.2 RPM包命名格式

RPM包命名格式如下:

name-version-release.architecture.rpm

name(名称):软件的名称,如nginx、httpd、mysql等,通常使用小写字母,可以包含数字和下划线,示例:nginx、postgresql、mariadb-server。

version(版本号):原始软件的版本号,通常由主版本号.次版本号.修订号组成,遵循软件原始发布版本,示例:1.20.1、2.4.6、5.7.38。

release(发布号):该版本的RPM包的修订号,通常包含发行版标识,格式:修订号.发行版标识,示例:9.el8(第9次构建,适用于RHEL 8),1.fc35(第1次构建,适用于Fedora 35),2.el7_9(第2次构建,适用于RHEL 7.9)。

architecture(架构):表示软件包支持的硬件平台,常见架构类型:x86_64:64位x86架构,i386/i686:32位x86架构,aarch64:64位ARM架构,noarch:与架构无关的包,ppc64le:IBM POWER架构,s390x:IBM System z架构。

特殊情况说明:

epoch(纪元号):当需要处理版本号冲突时使用,格式:epoch:name-version-release.architecture.rpm,示例:1:nginx-1.20.1-9.el8.x86_64.rpm。

debuginfo包:用于调试的符号表信息,命名格式:name-debuginfo-version-release.architecture.rpm,示例:nginx-debuginfo-1.20.1-9.el8.x86_64.rpm。

源码包(SRPM):扩展名为.src.rpm,架构通常为src,示例:nginx-1.20.1-9.el8.src.rpm。

版本比较规则:首先比较epoch(如果存在),然后比较version,最后比较release。

1.3 常见RPM命令

安装软件包:

rpm -ivh package.rpm

升级软件包:

rpm -Uvh package.rpm

卸载软件包:

rpm -e package

查询已安装的包:

rpm -qa | grep nginx

查看包信息:

rpm -qi nginx

查看包中的文件列表:

rpm -ql nginx

查询文件属于哪个包:

rpm -qf /etc/nginx/nginx.conf

一个完整的安装示例:

# 下载nginx RPM包
wget http://nginx.org/packages/rhel/8/x86_64/RPMS/nginx-1.20.1-1.el8.ngx.x86_64.rpm# 查看包信息
rpm -qip nginx-1.20.1-1.el8.ngx.x86_64.rpm# 安装包
rpm -ivh nginx-1.20.1-1.el8.ngx.x86_64.rpm# 确认安装
rpm -q nginx# 查看安装的文件
rpm -ql nginx# 启动服务
systemctl start nginx
2. 实践
2.1 构建RPM包

首先需要安装必要工具:

# 安装必要的RPM工具
sudo apt update
sudo apt install rpm
sudo apt install rpmbuild
sudo apt install rpmdevtools
sudo apt install alien# 安装构建工具
sudo apt install build-essential

创建RPM构建目录:

# 创建标准RPM目录结构
rpmdev-setuptree# 确认目录结构
ls -l ~/rpmbuild/

使用下面的脚本创建SPEC文件:

#!/bin/bash
###
# SPDX-License-Identifier: BSD-3-Clause
#
# Copyright (c) 2025 Once Day <once_day@qq.com>, All rights reserved.
## @FilePath: /devops/scripts/rpm_build.sh
# @Author: Once Day <once_day@qq.com>.
# @Date: 2025-05-22 15:00
# @info: Encoder=utf-8,Tabsize=4,Eol=\n.
#
# @Description:
#  构建RPM包
#
#### 开启shell调试
# set -x# 当前目录路径
export SOURCE_DIR=${SOURCE_DIR:-$(pwd)}# Shell 日志函数
# log "file" "line" "INFO" "This is a info message"
log() {local timestamp=$(date +"%Y-%m-%d %H:%M:%S")local script_name=$(basename "$1")local line_number=$2local level=$3local message=$4# 输出日志echo -e "[$timestamp] [$script_name:$line_number] [$3] $4"
}# 封装四个日志级别函数接口
# BASH_SOURCE[1] 表示调用者的文件名
# BASH_LINENO 表示调用者的行号
INFO() {log ${BASH_SOURCE[1]} $BASH_LINENO "INFO" "$1"
}WARN() {log ${BASH_SOURCE[1]} $BASH_LINENO "WARN" "$1"
}ERROR() {log ${BASH_SOURCE[1]} $BASH_LINENO "ERROR" "$1"
}DEBUG() {log ${BASH_SOURCE[1]} $BASH_LINENO "DEBUG" "$1"
}# 第一个参数是软件信息
if [ -n "$1" ]; thenSOFTNAME=$1# valgrind-3.21.0# SOURCE_NAME=valgrind# SOURCE_VERSION=3.21.0# 取出版本号SOURCE_VERSION=${SOFTNAME##*-}# 取出软件包名称SOURCE_NAME=${SOFTNAME%-*}
elseERROR "No sortware name specified, please specify it as the first argument."exit 1
fi
INFO "SOURCE_DIR: [$SOURCE_DIR]"
INFO "SOURCE_NAME: [$SOURCE_NAME]"
INFO "SOURCE_VERSION: [$SOURCE_VERSION]"# 第二个参数是构建产物目录
if [ -n "$2" ]; thenTARGET_DIR=$2# 使用绝对路径TARGET_DIR=$(realpath $TARGET_DIR)
elseERROR "No build target directory specified, please specify it as the first argument."exit 1
fi
INFO "TARGET_DIR: [$TARGET_DIR]"# 创建RPM包目录
RPM_DIR=${SOURCE_DIR}/rpmbuild
if [ ! -d "$RPM_DIR" ]; thenmkdir -p $RPM_DIR
fi
INFO "RPM_DIR: [$RPM_DIR]"# 创建RPM包目录结构
RPM_BUILD_DIR=${RPM_DIR}/BUILD
if [ ! -d "$RPM_BUILD_DIR" ]; thenmkdir -p $RPM_BUILD_DIR
fi
INFO "RPM_BUILD_DIR: [$RPM_BUILD_DIR]"RPM_RPMS_DIR=${RPM_DIR}/RPMS
if [ ! -d "$RPM_RPMS_DIR" ]; thenmkdir -p $RPM_RPMS_DIR
fi
INFO "RPM_RPMS_DIR: [$RPM_RPMS_DIR]"RPM_SRCS_DIR=${RPM_DIR}/SOURCES
if [ ! -d "$RPM_SRCS_DIR" ]; thenmkdir -p $RPM_SRCS_DIR
fi
INFO "RPM_SRCS_DIR: [$RPM_SRCS_DIR]"RPM_SPECS_DIR=${RPM_DIR}/SPECS
if [ ! -d "$RPM_SPECS_DIR" ]; thenmkdir -p $RPM_SPECS_DIR
fi
INFO "RPM_SPECS_DIR: [$RPM_SPECS_DIR]"RPM_SRCS_DIR=${RPM_DIR}/SOURCES
if [ ! -d "$RPM_SRCS_DIR" ]; thenmkdir -p $RPM_SRCS_DIR
fi
INFO "RPM_SRCS_DIR: [$RPM_SRCS_DIR]"# 编写RPM spec文件
SPEC_FILE=${RPM_SPECS_DIR}/${SOURCE_NAME}.spec
rm -f $SPEC_FILE
INFO "Delete Old SPEC_FILE: [$SPEC_FILE]"# 创建RPM spec文件
if [ ! -f "$SPEC_FILE" ]; thencat <<EOF > $SPEC_FILE
Name: $SOURCE_NAME
Version: $SOURCE_VERSION
Release: 1%{?dist}
Summary: $SOURCE_NAME RPM package
Group: Applications/System
BuildArch: x86_64License: (Unknown)
URL: (Unknown)%description
This package contains a pre-built binary of the $SOURCE_NAME program.%build
# No build needed%install
# Copy all extracted files into buildroot
cp -av $TARGET_DIR/* %{buildroot}/%files
%defattr(-,root,root,-)
%dir /
/*%changelog
* $(date +"%a %b %d %Y") Once Day <once_day@qq.com> - $SOURCE_VERSION-1
- Initial RPM package from pre-built filesEOF
fiINFO "SPEC_FILE: [$SPEC_FILE]"

运行该脚本,并且查看输出结果(SPEC文件):

在这里插入图片描述

SPEC文件用于打包 valgrind 程序的文件,其字段含义如下:

  • 基本信息部分:软件包名称是 valgrind,版本号为 3.21.0,Release 版本号为 1,是一个系统工具类软件包,仅支持 x86_64 架构,License 和 URL 信息未指定。

  • 功能描述:这个 RPM 包含预编译好的 valgrind 程序文件。

  • 构建和安装:不需要编译构建步骤,安装时会将 /root/workspace/packages/build/release-x86_64-local/valgrind-3.21.0/ 目录下的所有文件复制到最终安装目录。

  • 文件部分:包含根目录(/)及其下所有文件,所有文件的属主和属组都设置为 root。

  • 更新日志:2025年5月26日由 Once Day 创建的初始版本,这是首次将预编译文件打包成 RPM。

这是一个相对简单的 spec 文件,主要用于将已编译好的 valgrind 程序打包成 RPM 格式以便于分发安装。

最后,执行实际打包操作:

rpmbuild -bb rpmbuild/SPECS/valgrind.spec

最终生成文件在~/rpmbuild/RPMS/目录下:

root@de92817fb2e7:~/workspace/packages# ll /root/rpmbuild/RPMS/x86_64/
total 18876
drwxr-xr-x 2 root root     4096 May 22 10:45 ./
drwxr-xr-x 3 root root     4096 May 22 10:45 ../
-rw-r--r-- 1 root root 19317648 May 26 23:31 valgrind-3.21.0-1.x86_64.rpm
2.2 安装RPM包

使用下面的命令安装上述软件:

rpm --nodeps --notriggers -ivh --force valgrind-3.21.0-1.x86_64.rpm

主要选项含义:

  • -i: install 的缩写,表示安装操作。
  • -v: verbose 的缩写,显示详细的安装过程信息。
  • -h: hash 的缩写,显示安装进度条。
  • --nodeps: 忽略包的依赖关系检查,强制安装即使缺少依赖包。
  • --notriggers: 忽略安装过程中的触发器脚本执行。
  • --force: 强制安装,即使覆盖现有文件。

这是一个比较"野蛮"的安装方式,忽略了依赖检查,可能导致程序无法正常运行,也跳过了触发器脚本,可能影响某些配置的自动化设置,并且强制覆盖现有文件,可能破坏系统中的其他程序。

这种安装方式通常用于特殊情况,需要覆盖安装或降级安装,所以对于日常开发调试来说,非常合适。

一般情况下推荐使用 rpm -ivh

2.3 RPM优化(压缩速度)

新版本的RPM与旧版本buildroot配合时,可能会出现Error: Empty %files file的报错问题,这是由于这部分文件不会被预先安装,但是RPM会提前检查,从而出现冲突,添加--define "__spec_install_pre /bin/true"选项,这样就可以兼容旧版本buildroot了。

通常情况下,RPM使用gzip进行压缩,只能单线程工作,在打包文件较大时,效率非常低,需要几十秒的时间。

RPM包的压缩涉及几个主要方面:

  • 常用压缩格式:gzip (.gz):传统格式,压缩比一般,速度快;bzip2 (.bz2):较好压缩比,速度较慢;xz (.xz):最佳压缩比,CPU占用较高;zstd (.zst):新格式,在速度和压缩比间较好平衡。

  • 压缩级别:gzip: 1-9级,默认6;bzip2: 1-9级,默认9;xz: 0-9级,默认6;zstd: 1-19级,默认3。

常用命令选项:

# 使用gzip压缩
--define "_binary_payload w9.gzdio"# 使用bzip2压缩
--define "_binary_payload w9.bzdio"# 使用xz压缩(带线程数)
--define "_binary_payload w6T8.xzdio"# 使用zstd压缩(带线程数)
--define "_binary_payload w3T8.zstdio"

性能特点:gzip: 速度最快,压缩比最低;bzip2: 速度和压缩比均中等;xz: 最高压缩比,速度最慢;zstd: 较好压缩比,速度接近gzip。小型包:使用gzip即可。大型包:考虑xz或zstd。需要快速部署:选择gzip或zstd。注重存储空间:选择xz。

对于大型的rpm包,通常可以使用下面的选项参数:

--define "_binary_payload w0T24.xzdio"

参数组成:

  • w: 表示写入方式
  • 0: 存储文件的格式(0代表标准格式)
  • T: 表示使用新的标头格式
  • 24: 指定并行压缩的线程数(这里是24线程)
  • .xzdio: 使用 xz 压缩算法进行压缩

通过指定 24 线程进行并行压缩,显著提高压缩速度,使用 xz 压缩算法,提供较好的压缩比。

相关文章:

  • 【四】频率域滤波(下)【830数字图像处理】
  • 机械设计插件
  • 洛谷题目:P2785 物理1(phsic1)- 磁通量 题解 (本题较难)
  • 【教学类-36-09】20250526动物面具描边(通义万相)对称图40张,根据图片长宽,自动旋转图片,最大化图片
  • top查看 CPU使用情况
  • 考研408《计算机组成原理》复习笔记,第二章(3)数值数据的运算(浮点数计算篇)
  • Linux GPIO子系统深度解析:从历史演进到实战应用
  • MMAction2重要的几个配置参数
  • 【C++】内存管理,深入解析new、delete
  • 预算超支、进度延误?工程企业如何实现精准管理?
  • 计算机系统简介(二)
  • 数据结构基础知识补充
  • BGP配置命令详细框架
  • 清除谷歌浏览器中的“您的浏览器由所属组织/贵单位管理”
  • Vuex Actions: 异步操作
  • C 语言学习笔记(指针6)
  • vue + ant-design + xlsx 实现表格数据导出
  • jsAPI:Intl.DateTimeFormat 属性含义
  • 原子操作(Atomic Operations)在SOC中的应用场景
  • LINUX安装运行jeelowcode前端项目
  • 手机网站和app有什么区别/龙网网络推广软件
  • 网站中信息更新怎么做的/百度网站是什么
  • 做影视网站怎么/北京网站快速排名优化
  • 做网站工作怀孕/网络科技公司骗了我36800
  • 可以做微网站的第三方平台有哪些/seo案例分析
  • 北京做网站哪个好/怎么做网络广告