linux-rpm

2021-11-17

为啥需要有rpm包?

目标:生成一个软件,安装软件后就可以键入hello就echo出hello world。

image-20211118150420103

步骤:

1.写源码,分别用bash、python、c语言实现,分别叫bello.sh、pello.py、cello.c

bash:
#!/usr/bin/bash
echo Hello world

python:
#!/usr/bin/env python
print("Hello World")

c:
#include <stdio.h>

int main(void) {
    printf("Hello World\n");
    return 0;
}

2.根据情况处理源码后,与/usr/bin/hello进行关联

2.1 bash处理


2.2 python处理


3.3 c处理


我们写一个shell脚本,提供的功能就是echo一个hello world。

#!/usr/bin/bash
echo Hello world

此时我想把当前的脚本直接作为一个命令使用,可以用install命令

install -m 755 hello-world.sh /usr/bin/hello-world	//install命令详解:https://man.linuxde.net/install

此时就可以正常使用hello-world命令了

image-20211117153116366

但此时我们有一个更新输出内容,希望通过hello-world命令输出New Hello World, 需要的操作大致分为两步

1.将原来的hello-world.sh中内容进行修改;这里我们可以直接进行修改,看起来很简单,但是仔细分析这个其实是一个需要靠人工的操作,需要打开文件、找到行数、插入新内容、保存退出的操作,但使用patch命令可以简化操作。(虽然生产patch文件需要一些的操作)

//生成new-hello-world.sh
cat > new-hello-world.sh <<EOF
#!/usr/bin/bash
echo New Hello world
EOF	
//生成patch文件
diff -Naur new-hello-world.sh hello-world.sh > first.patch

image-20211117154949830

2.把新的patch打进去,然后重新使用install命令关联/usr/bin/hello-world

patch < hello-world.sh
install -m 755 hello-world.sh /usr/bin/hello-world

image-20211117155232125

最后我们不需要使用这个命令了,希望把这个命令删除掉

rm hello-world.sh /usr/bin/hello-world

image-20211117155734406

上面三个需求就是一个软件在其生命周期可能遇到的情况,而rpm就提供了这一系列的功能。

对于安装、升级、卸载等情况下要怎么处理就记录在spec中。

rpm相关的包:rpm-build rpm-devel rpmlint (疑惑点:一开始没有这个三个rpm包的时候,是怎么编出来这三个包的)

先不介绍spec文件中的具体含义,先看一个简单的spec文件:

Name:       hello-world
Version:    1
Release:    1
Summary:    Most simple RPM package
License:    FIXME

%description
This is my first RPM package, which does nothing.

%prep
# we have no source, so nothing here

%build
cat > hello-world.sh <<EOF
#!/usr/bin/bash
echo Hello world
EOF

%install
mkdir -p %{buildroot}/usr/bin/
install -m 755 hello-world.sh %{buildroot}/usr/bin/hello-world.sh

%files
/usr/bin/hello-world.sh

%changelog
# let's skip this for now

然后使用命令:

rpmdev-setuptree

image-20211117162615364

rpmbuild -ba hello-world.spec

image-20211117162652505

分析spec脚本中的作用:

C语言和PY脚本的分析:

C语言:

hello的源码

#include <stdio.h>

int main(void) {
    printf("Hello World\n");
    return 0;
}

我们需要先编译为二进制,然后才能调用

gcc -g -o cello cello.c

image-20211117164243193

大型软件常用的做法,自动化构建是通过创建一个Makefile然后运行GUN的make程序来完成的。

Makefile

cello:
        gcc -g -o cello cello.c

clean:
        rm cello

image-20211117164534977

Makefile其中还可以做更多操作,内置软件安装到系统的一种流行的自动化方法是使用该 make install命令

cello:
        gcc -g -o cello cello.c

clean:
        rm cello

install:
        mkdir -p $(DESTDIR)/usr/bin
        install -m 0755 cello $(DESTDIR)/usr/bin/cello

image-20211117172241857

python:

pello.py

#!/usr/bin/env python
print("Hello World")

pyc文件和py的区别:https://cloud.tencent.com/developer/news/361425

pyc是一种二进制文件,加载速度会更快,所以有时候需要将py脚本变成pyc

python -m compileall pello.py

-m:库中的python模块用作脚本去运行

。一个 SRPM 包含源代码、可选的补丁和一个 SPEC 文件,它描述了如何将源代码构建到二进制 RPM 中。二进制 RPM 包含从源代码和补丁构建的二进制文件

image-20211118130203152

image-20211118130225258

名词解释

RPM:是Red-Hat Package Manager(红帽软件包管理器)的缩写,这一文件格式名称虽然打上了RedHat的标志,但是其原始设计理念是开放式的,包括OpenLinux、S.u.S.E.以及Turbo Linux等Linux的分发版本都有采用,可以算是公认的行业标准了。

spec:specification(规格),软件包描述文件,即SPEC文件。这个文件中包含了软件包的诸多信息,如软件包的名字、版本、类别、说明摘要、创建时要执行什么命令、安装时要执行什么操作、以及软件包所要包含的文件列表等。

如果您看到一个不熟悉的宏,您可以使用以下命令对其进行评估:

$ rpm --eval %{_MACRO}

一个常见的宏是%{?dist},表示“分发标签”。它表示用于构建的分布。

例如:

# On a RHEL 7.x machine
$ rpm --eval %{?dist}
.el7

# On a Fedora 23 machine
$ rpm --eval %{?dist}
.fc23

看下rpmbuild的目录结构:

/home/user/rpmbuild/
|-- BUILD
|-- RPMS
|-- SOURCES
|-- SPECS
`-- SRPMS

image-20211118134540717

NameVersionRelease指令包括RPM软件包的文件名。RPM 包维护人员和系统管理员通常将这三个指令称为NVRNVR,因为 RPM 包文件名具有NAME-VERSION-RELEASE格式。

rpm命令:https://www.runoob.com/linux/linux-comm-rpm.html

常用命令组合:

rpm -qa:查询所有安装的rpm包
rpm -ivh:安装具体的rpm包
rpm -Uvh: 升级,如果没安装就执行安装
rpm -q(p)l: 查询的rpm安装的文件,如果rpm还没有安装,则加上'p'
rpm -q(p)i: 查询的rpm的基本信息
rpm -q(p)f: 查询文件归属哪个rpm包
rpm -e --nodeps: 无视依赖强行删除rpm包
rpm -ivh --nodeps --force: 无视依赖,无视冲突强行安装rpm包
rpm2cpio xxxx.rpm | cpio -ivd: 命令提取出原 RPM 包中所需的系统文件

image-20211117144945288

rpm的query显示出的内容、安装、卸载、升级等所需要的工作都是依赖spec文件,所以spec是specification(规格)的简写,其实说成recipe(配方)更加合适。

Name:       hello-world
Version:    1
Release:    1
Summary:    Most simple RPM package
License:    FIXME

%description
This is my first RPM package, which does nothing.

%prep
# we have no source, so nothing here

%build
cat > hello-world.sh <<EOF
#!/usr/bin/bash
echo Hello world
EOF	
//用法:https://blog.csdn.net/weixin_43958556/article/details/116379910?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link

%install
mkdir -p %{buildroot}/usr/bin/	
//p的含义:--parents
install -m 755 hello-world.sh %{buildroot}/usr/bin/hello-world.sh

%files
/usr/bin/hello-world.sh

%changelog
# let's skip this for now
$ python -m compileall pello.py
-m/compileall:http://t.zoukankan.com/bonelee-p-8619391.html
$ file pello.pyc
pello.pyc: python 2.7 byte-compiled
打补丁
$ diff -Naur cello.c.orig cello.c > cello-output-first-patch.patch
patch < cello-output-first-patch.patch

分类

RPM软件包分为二进制包(Binary)、源代码包(Source)和Delta包三种。二进制包可以直接安装在计算机中,而源代码包将会由RPM自动编译、安装。源代码包经常以src.rpm作为后缀名

命令

rpmbuild\rpm

rpmbuild

rpm怎么用