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 压缩算法,提供较好的压缩比。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/84550.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

国内可做大批量pcb的工厂有哪些?

在电子产业升级浪潮中&#xff0c;PCB作为电子设备的基础载体&#xff0c;其批量生产能力直接决定着终端产品的市场响应速度与品质稳定性。本文精选五家具备核心竞争力的厂商&#xff0c;从工艺深度、产能规模到服务模式展开剖析&#xff0c;为采购决策提供专业参考。 猎板PCB…

【视频】使用海康SDK保存的MP4无法在浏览器(html5)中播放

1、问题描述 在使用海康 SDK 的 NET_DVR_SaveRealData 接口&#xff0c;将视频流保存成MP4文件后&#xff0c;通过浏览器无法播放MP4&#xff0c;播放其它的MP4正常。 2、原因分析 对比可以正常播放的MP4 和 无法播放的MP4文件&#xff0c;比较它们的详细信息&#xff0c;发…

AI时代新词-生成对抗网络(GAN)

一、什么是生成对抗网络&#xff08;GAN&#xff09;&#xff1f; 生成对抗网络&#xff08;Generative Adversarial Network&#xff0c;简称GAN&#xff09;是一种由生成器&#xff08;Generator&#xff09;和判别器&#xff08;Discriminator&#xff09;组成的深度学习模…

使用AutoKeras2.0的AutoModel进行结构化数据回归预测

1、First of All: Read The Fucking Source Code import autokeras as ak import numpy as np from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error# 生成数据集 np.random.seed(42) x np.random.rand(1000, 10) # 生成1…

实战设计模式之访问者模式

概述 访问者模式允许我们在不改变类的前提下&#xff0c;向已有类添加新的功能。简单来说&#xff0c;就是将算法与对象的数据结构进行分离的一种方法。在实际应用中&#xff0c;当我们需要对一组对象执行一些操作&#xff0c;而这些操作又需要随着需求的变化而不断变化时&…

centos7.9使用docker-compose安装kafka

docker-compose配置文件 services:zookeeper:image: confluentinc/cp-zookeeper:7.0.1hostname: zookeepercontainer_name: zookeeperports:- "2181:2181"environment:ZOOKEEPER_CLIENT_PORT: 2181ZOOKEEPER_TICK_TIME: 2000kafka:image: confluentinc/cp-kafka:7.0…

STM32:Modbus通信协议核心解析:关键通信技术

知识点1【 Modbus通信】 1、Modbus的概述 Modbus是OSI模型第七层的应用层报文传输协议 协议&#xff1a;说明有组包和解包的过程 2、通信机制 Modelbus是一个请求/应答协议 通信机制&#xff1a;主机轮询&#xff0c;从机应答的机制。每个从设备有唯一的地址&#xff0c;主…

LeetCode 3362.零数组变换 III:贪心+优先队列+差分数组——清晰题解

【LetMeFly】3362.零数组变换 III&#xff1a;贪心优先队列差分数组——清晰题解 力扣题目链接&#xff1a;https://leetcode.cn/problems/zero-array-transformation-iii/ 给你一个长度为 n 的整数数组 nums 和一个二维数组 queries &#xff0c;其中 queries[i] [li, ri] …

ORM++ 封装实战指南:安全高效的 C++ MySQL 数据库操作

ORM 封装实战指南&#xff1a;安全高效的 C MySQL 数据库操作 一、环境准备 1.1 依赖安装 # Ubuntu/Debian sudo apt-get install libmysqlclient-dev # CentOS sudo yum install mysql-devel# 编译时链接库 (-I 指定头文件路径 -L 指定库路径) g main.cpp -stdc17 -I/usr/i…

JESD204B 协议介绍

一、协议概述 JESD204B是由JEDEC&#xff08;固态技术协会&#xff09;制定的高速串行接口标准&#xff0c;专为模数转换器&#xff08;ADC&#xff09;、数模转换器&#xff08;DAC&#xff09;与逻辑器件&#xff08;如FPGA、ASIC&#xff09;之间的数据传输设计。其核心目标…

yolov8,c++案例汇总

文章目录 引言多目标追踪案例人体姿态估计算法手势姿态估计算法目标分割算法 引言 以下案例,基于c,ncnn,yolov8既可以在windows10/11上部署, 也可以在安卓端部署, 也可以在嵌入式端部署, 服务器端可支持部署封装为DLL,支持c/c#/java端调用 多目标追踪案例 基于yolov8, ncnn,…

运动规划实战案例 | 图解基于状态晶格(State Lattice)的路径规划(附ROS C++/Python仿真)

目录 1 控制采样 vs 状态采样2 State Lattice路径规划2.1 算法流程2.2 Lattice运动基元生成2.3 几何代价函数2.4 运动学约束启发式 3 算法仿真3.1 ROS C仿真3.2 Python仿真 1 控制采样 vs 状态采样 控制采样的技术路线源自经典的运动学建模思想。这种方法将机器人的控制指令空…

BERT框架:自然语言处理的革命性突破

引言 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;2018年Google推出的BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;框架无疑是一场革命。作为基于Transformer架构的双向编码器表示模型&#xff0c;BERT通过预训练学习…

【Fifty Project - D31】

结束了一个超级消耗周末&#xff0c;满安排之健身梅溪湖游泳做饭喝酒羽毛球赛 完全力竭了&#xff0c;久久不能恢复过来&#xff0c;暂停健身安排了 端午后再继续 今日完成记录 TimePlan完成情况7&#xff1a;30 - 8&#xff1a;10有氧爬坡√9&#xff1a;00 - 11&#xff1a;…

信息学奥赛一本通 1547:【 例 1】区间和

【题目链接】 ybt 1547&#xff1a;【 例 1】区间和 【题目考点】 1. 线段树 2. 树状数组 【解题思路】 本题要求维护区间和&#xff0c;实现单点修改、区间查询。 解法1&#xff1a;线段树 线段树原理&#xff0c;及实现方法见&#xff1a;洛谷 P3374 【模板】树状数组…

力扣面试150题--求根节点到叶节点数字之和

Day 48 题目描述 思路 我们利用sum这个全局变量来保存总和值&#xff0c;递归函数sum来计算每个根到叶子节点路径所代表的数&#xff0c;由于我们需要遍历到每条根到叶子节点的路径&#xff0c;所有我采取了前序遍历&#xff0c;如果不是叶子节点&#xff0c;就计算到该节点代…

DJI上云API官方demo学习

1、websocket&#xff0c;所在位置如下图&#xff0c;调用的可以用//websocket搜索 2、用到的http客户端&#xff0c;axios 3、很多和后端交互都是走的http请求

uniapp开发小程序,如何根据权限动态配置按钮或页面内容

前言 写了好几个项目&#xff0c;发现小程序对权限控制非常麻烦&#xff0c;于是有了这个想法&#xff0c;但是网上找了一圈没有一个比较完善的讲解&#xff0c;因为小程序不支持自定义指令&#xff0c;所以不能像后台那样方便&#xff0c;于是就将几个博主的想法结合。 思路就…

LSTM+Transformer混合模型架构文档

LSTMTransformer混合模型架构文档 模型概述 本项目实现了一个LSTMTransformer混合模型&#xff0c;用于超临界机组协调控制系统的数据驱动建模。该模型结合了LSTM的时序建模能力和Transformer的自注意力机制&#xff0c;能够有效捕捉时间序列数据中的长期依赖关系和变量间的复…

测量尺子:多功能测量工具,科技改变生活

测量尺子是一款专业的测距仪测量万能工具箱类型手机APP&#xff0c;旨在为用户提供最贴心的测量助手。它拥有和现实测量仪器一样的测量标准&#xff0c;更简单便捷且精准的测量方式&#xff0c;最新AR科技测量更是大大拓宽了可以被测量的高度和深度。无论是日常使用、学习还是工…