软件运行和编译

​ 在Windows上,我们可以通过exe或者msi格式的安装包来使用指引的方式将我们想要的软件按照我们的需求安装到我们的电脑上,同时还可以设置软件应该放置在哪。软件的全局变量、注册表配置、开机自启等功能都会一并自动配置。

​ 但到了Linux上,也有相应的工具来帮助我们自动安装所需工具。但在Linux的安装却无法指定安装。为什么?

​ Linux的安装包打包后一般为rpm(rhel)deb(debian)等后缀。在安装包其中已经指定好了二进制程序放置的路径在哪,不可更改。yum,apt,dnf等包管理工具只是执行找到的安装包里的命令,并不能更改其中的具体路径参数。所以Linux中的自动化安装也有自己的缺点。

​ 但Linux中可以二进制安装。即下载对应的压缩包文件而不是安装包文件。自己放置到对应目录后再手动写出配置文件或修改其中自带的配置文件。然后完成安装,这样会提供更大的自定义空间,但操作会更麻烦。

​ 本身使用Linux就是个麻烦 ( ´•̥̥̥ω•̥̥̥` )

软件接口概念

​ 首先介绍一下应用程序的早期标准,也就是软件是怎么实现统一的。这个接口的作用是对软件的编译提供一个统一的标准。如果两台设备系统不同,但遵从一样的接口格式,那么在A设备可以编译后运行的代码,在B设备上同样可以编译后运行

​ 软件接口是连接软件与操作系统的底层桥梁

ABI

​ Application Binary Interface :应用程序二进制接口

注:在 windows 中与 linux 中的 ABI 格式是不兼容的(各自有各自的标准)

  • windows 中的是 PE ( Portable Executable ) 格式
  • Linux 中的是 ELF ( Executable and Linkable Format ) 格式

linux 中不同版本的 ABI 由于格式相同,所以程序也是互相通用的

(可能因为内核版本等原因可能会存在不支持的情况,但你一定能通过寻找旧版本软件去进行使用)

API

​ Application Programming Interface,API接口在现在、可以在 Windows 和 linux 提供完全相同的接口。虽然本身在这些系统上的实现却可能迥异。

​ 早期的 API 在 Windows 上和 Linux 上其实也使用的不同标准。但后来因为软件移植需求日益增大, POSIX 标准被规定了出来。

​ POSIX:Portable Operating System Interface :可移植操作系统接口。定义了操作系统应该为应用程序提供的接口。现在 Linux 和 Windows 都要实现基本的 POSIX 标准。程序就可以在源码层面上可以移植了

注:但真正移植还是需要做兼容性调整。因为双方只是遵从基本的标准,但一些细小方面的实现方式还是不同。直接将代码移植编译只会导致出错。

软件包和包管理工具

​ Linux 中有着官方的包管理工具用于对软件进行管理。同时也得了解一下软件包的来源

软件包介绍

​ 在接口标准等等没现在规范时,开源软件基本只提供 .tar.gz 打包的源码文件(这可以减少开发者的上传时间,源码的大小远远小于编译好后的程序大小)。同时那时候的包管理工具效果很差,它只会查看你要安装的程序需要什么依赖,然后需要你手动一个个下载,甚至有些依赖它根本不告诉你,只能去依靠询问作者或查找WIKI去确定问题所在。

​ 现在网络发达后,其中基本都是编译好的二进制文件了,你只需要解压,放置在你想放置的目录下。然后配置变量和系统管理就可以像指令安装的程序一样使用了。

(有些作者可能会制作成rpm,deb包之类的,但不建议下载这个离线安装。因为可能还需要一些依赖之类的,使用更现代的包管理直接安装可以自动安装依赖)

包管理工具

软件包管理器功能:

将编译好的应用程序的各组成文件打包一个或几个程序包文件,利用包管理器可以方便快捷地实现程序包的安装、卸载、查询、升级和校验等管理操作

主流的程序包管理器:

  • redhat:rpm文件, rpm 包管理器,rpm:Redhat Package Manager,RPM Package Manager
  • debian:deb文件, dpkg 包管理器

包命名

源代码打包文件命名

1
2
3
4
5
6
7
8
name-VERSION.tar.gz|bz2|xz 
VERSION: major.minor.release

#nginx-1.22.0.tar.gz

#major     主版本号
#minor     次版本号
#release   修正版本号

rpm包命名方式

1
2
3
4
5
6
7
8
9
10
11
12
13
name-VERSION-release.arch.rpm 
VERSION: major.minor.release

release:release.OS

#http-parser-2.8.0-9.el8.x86_64.rpm
#httpd-2.4.37-41.module+el8.5.0+695+1fa8055e.x86_64.rpm
#nginx-1.14.1-9.module+el8.4.0+542+81547229.x86_64.rpm

#major     主版本号
#minor     次版本号
#release   修正版本号
#el8 EL是Red Hat Enterprise Linux(EL)的缩写, EL8是Red Hat 8.x,CentOS 8.x,el8.4.0+ 是指 适配redhat8.4.0以上及centos8.4.0以上的系统

常见的arch:

  • x86: i386, i486, i586, i686
  • x86_64: x64, x86_64, amd64
  • powerpc: ppc
  • 跟平台无关:noarch

分类和拆包

软件包为了管理和使用的便利,会将一个大的软件分类,放在不同的子包中。

包的分类

  • Application-VERSION-ARCH.rpm: 主包
  • Application-devel-VERSION-ARCH.rpm 开发子包
  • Application-utils-VERSION-ARHC.rpm 其它子包
  • Application-libs-VERSION-ARHC.rpm 其它子包

包的依赖

软件包之间可能存在依赖关系,甚至循环依赖,即:A包依赖B包,B包依赖C包,C包依赖A包,安装软件包时,会因为缺少依赖的包,而导致安装包失败。

解决依赖包管理工具:

  • yum:rpm包管理器的前端工具
  • dnf:Fedora 18+ rpm包管理器前端管理工具,CentOS 8 版代替 yum
  • apt:deb包管理器前端工具
  • zypper:suse上的rpm前端管理工具

程序包管理器相关文件

1 包文件组成 (每个包独有)

  • 包内的文件
  • 元数据,如:包的名称,版本,依赖性,描述等
  • 可能会有包安装或卸载时运行的脚本

2 数据库(公共):/var/lib/rpm

  • 程序包名称及版本
  • 依赖关系
  • 功能说明
  • 包安装后生成的各文件路径及校验码信息

获取程序包的途径

软件包需要事先将源码进行编译后打包形成,获取包的途径如下:

系统发版的光盘或官方网站

CentOS镜像:

https://www.centos.org/download/

http://mirrors.aliyun.com

http://mirrors.sohu.com

http://mirrors.163.com

Ubuntu 镜像:

http://cdimage.ubuntu.com/releases/

http://releases.ubuntu.com

第三方组织提供

Fedora-EPEL:Extra Packages for Enterprise Linux

https://fedoraproject.org/wiki/EPEL

https://mirrors.aliyun.com/epel/?spm=a2c6h.13651104.0.0.3bc47dfaZpesAr

Rpmforge:RHEL推荐,包很全,即将关闭

http://repoforge.org/

Community Enterprise Linux Repository:支持最新的内核和硬件相关包

http://www.elrepo.org

软件项目官方站点

http://yum.mariadb.org/10.4/centos8-amd64/rpms/

http://repo.mysql.com/yum/mysql-8.0-community/el/8/x86_64/

搜索引擎

注意:第三方包建议要检查其合法性,来源合法性程序包的完整性

http://pkgs.org

http://rpmfifind.net

http://rpm.pbone.net

https://sourceforge.net/

自己制作

将源码文件,利用工具,如:rpmbuild,fpm等工具制作成rpm包文件

包管理器 rpm

CentOS系统上使用rpm命令管理程序包

功能:安装、卸载、升级、查询、校验、数据库维护

包安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
rpm {-i|--install} [install-options] PACKAGE_FILE…
-v|verbose #显示详细信息
-vv #更详细
-h #显示安装进度条
--test #测试安装,但不真正执行安装,即dry run模式
--nodeps   #忽略依赖关系
--replacefiles      #忽略软件包之间的冲突的文件
--replacepkgs       #如果软件包已经有了,重新安装软件包
--nosignature #不检查来源合法性
--nodigest #不检查包完整性
--noscripts #不执行程序包脚本,相当于 --nopre --nopost --nopreun --nopostun -
-nopretrans --noposttrans
--nopre #不执行程序包中安装前脚本
--nopost #不执行程序包中安装前脚本
--nopreun #不执行程序包中卸载前脚本
--nopostun #不执行程序包中卸载后脚本
--nopretrans #安装前不执行与程序同名脚本
--noposttrans #安装后不执行与程序同名脚本

#常用组合
rpm -ivh PACKAGE_FILE ...

升级和降级

1
2
3
4
5
6
7
8
9
10
11
rpm {-U|--upgrade} [install-options] PACKAGE_FILE... 
rpm {-F|--freshen} [install-options] PACKAGE_FILE...

upgrade #安装有旧版程序包,则“升级”,如果不存在旧版程序包,则“安装”
freshen #安装有旧版程序包,则“升级”, 如果不存在旧版程序包,则不执行安装操作
--oldpackage #降级
--force     #强制安装

#常用组合
rpm -Uvh PACKAGE_FILE ...
rpm -Fvh PACKAGE_FILE ...

升级注意项:

  • 不要对内核做升级操作;Linux支持多内核版本并存,因此直接安装新版本内核
  • 如果原程序包的配置文件安装后曾被修改,升级时,新版本提供的同一个配置文件不会直接覆盖老版本的配置文件,而把旧版本文件重命名(FILENAME.rpmnew)后保留

包查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
rpm {-q|--query} [select-options] [query-options]

[select-options]
-a   #所有包
-f   #查看指定的文件由哪个程序包安装生成
-p rpmfile #针对尚未安装的程序包文件做查询操作
--whatprovides CAPABILITY   #查询指定的CAPABILITY由哪个包所提供
--whatrequires CAPABILITY   #查询指定的CAPABILITY被哪个包所依赖
[query-options]
--changelog #查询rpm包的changelog
-c           #查询程序的配置文件
-d #查询程序的文档
-i #information(详细信息)
-l #查看指定的程序包安装后生成的所有文件
--scripts #程序包自带的脚本
--provides #列出指定程序包所提供的CAPABILITY
-R #查询指定的程序包所依赖的CAPABILITY

#常用查询组合
-qi PACKAGE
-qf FILE
-qc PACKAGE
-ql PACKAGE
-qd PACKAGE
-qpi PACKAGE_FILE
-qpl PACKAGE_FILE
-qa

包卸载

1
rpm {-e|--erase} [--allmatches] [--nodeps] [--noscripts] [--notriggers] [--test] PACKAGE_NAME ...

包校验

在安装包时,系统也会检查包的来源是否是合法的

检查包的完整性和签名

1
rpm -K | checksig rpmfile

检查前一定要确保自己有对应的公钥文件

数据库

rpm包安装时生成的信息,都放在rpm数据库中

1
2
3
4
5
6
[root@rocky86 v]# ll /var/lib/rpm
total 144016
-rw-r--r--. 1 root root   5218304 Jul 27 16:11 Basenames
-rw-r--r--. 1 root root     16384 Jul 20 16:09 Conflictname
-rw-r--r--  1 root root    286720 Jul 27 16:21 __db.001
......

可以重建数据库

1
2
3
4
rpm {--initdb|--rebuilddb} 

initdb #初始化,如果事先不存在数据库,则新建之,否则,不执行任何操作
rebuilddb #重建已安装的包头的数据库索引目录

包更新日志

1
rpm -q --changelog packageName

yum和dnf

​ CentOS使用 yum, dnf 解决 rpm 的包依赖关系

​ YUM: Yellowdog Update Modififier,rpm的前端程序,可解决软件包相关依赖性,可在多个库之间定位软件包,up2date的替代工具

​ CentOS 8 用dnf 代替了yum ,不过保留了和yum的兼容性,配置也是通用的

yum/dnf 工作原理

yum/dnf 是基于 C/S 模式 metadata

  • yum 服务器存放rpm包和相关包的元数据库
  • yum 客户端访问yum服务器进行安装或查询等

yum 实现过程

先在yum服务器上创建 yum repository(仓库),在仓库中事先存储了众多rpm包,以及包的相关的元数据文件(放置于特定目录repodata下),当yum客户端利用yum/dnf工具进行安装包时,会自动下载repodata中的元数据,查询元数据是否存在相关的包及依赖关系,自动从仓库中找到相关包下载并安装。

创建新源

当使用yum install xxx 或 yum update xxx 时

先去看源能不能连上,如果能连上,则下载源里面的 repodata(如果不是新源,则直接查询本地己存在的repodata)

然后再去 repodata 里面查询,是否有 xxx 包,如果有,则去源的服务器下载 xxx.rpm(包括依赖包)

然后开始安装,完成后删除包信息

yum命令

yum命令的用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
yum [options] COMMAND

#常用选项
-c file|--config file #指定配置文件,默认使用/etc/yum.conf
-v|--verbose #显示详细信息
-b|--best #尝试在可用包中寻找最匹配的版本
-y|--assumeyes #自动回答为 yes
--nogpgcheck #不进行包校验
--repo repoid|--repoid repoid #指定repo源
--enablerepo repoid #临时启用repo源,可用通配符
--disablerepo repoid #临时禁用repo源,可用通配符
--nodocs             #不安装文档
--skip-broken #跳过有问题的包
--enable #启用源,配合 config-manager
--disable #禁用源,配合 config-manager
-x package|--exclude package|--excludepkgs package #排除指定包,可用通配符
--downloadonly #只下载,不安装

#常用子命令
autoremove               #卸载包,同时卸载依赖
check-update             #检查可用更新
clean                    #清除本地缓存
downgrade                #包降级
group                    #包组相关
help                     #显示帮助信息
history                  #显示history
info                     #显示包相关信息
install                  #包安装
list                     #列出所有包
makecache                #重建缓存
reinstall                #重装
remove                   #卸载
repolist                 #显示或解析repo源
search                   #包搜索,包括包名和描述

显示仓库列表

格式:

1
2
3
4
5
6
7
8
yum repolist [options].

#常用选项
-v|--verbose #显示详细信息
--repo repoid|--repoid repoid #指定repo源
--all #显示所有源
--enabled #所有enabled状态的源,默认项
--disabled

安装程序包

1
2
3
4
5
6
7
yum install [options] PACKAGE [...]
yum reinstall [options] PACKAGE [...]

#常用选项
--installroot path #指定安装目录
--downloadonly #只下载,不安装
--downloaddir path|--destdir path #指定下载目录,如果下载目录不存在,则自动创建

卸载程序包

1
2
yum remove [options] PACKAGE [...]
yum erase [options] PACKAGE [...] #包括配置文件等,删除更干净

升级和降级

1
2
3
yum update [options] PACKAGE [...] 	    #升级
yum downgrade [options] PACKAGE [...] #降级
yum check-update #检查可用升级

查询

1
2
3
4
yum info [options] PACKAGE [...]	 #查看程序包的 information 信息
yum provides [options] PROVIDE #查看文件是由哪个包提供  
yum search [options] KEYWORD #根据关健字搜索,范围包括包名和描述信息
yum deplist [options] PACKAGE [...] #查询包的依赖

仓库缓存

缓存目录为

centos8:/var/cache/dnf/

centos7:/var/cache/yum/

1
2
yum clean [options] {metadata,packages,dbcache,expire-cache,all} 	#清空缓存
yum makecache #构建缓存

查看yum事务历史

yum 执行安装卸载命令会记录到相关日志中

日志文件 /var/log/dnf.log ( /var/log/yum.log )

1
2
3
4
5
6
7
yum history [options] [info|list|redo|undo]
yum history #默认查看所有
yum history list #同上
yum history package #查看与指定包有关的日志
info N #查看第N条记录的具体执行内容
undo N #回滚第N条记录
redo N #重新执行第N条记录

安装及升级本地程序包

1
2
yum localinstall|install [options] rpmfile1 [...]  #安装本地RPM包
yum localupdate|update [options] rpmfile1 [...] #使用本地RPM包升级

包组管理的相关命令

1
2
3
4
5
yum grouplist [options]				    #列出所有包组
yum groupinstall [options] group1 [...] #包组安装
yum groupupdate [options] group1 [...] #包组升级
yum groupremove [options] group1 [...] #包组卸载
yum groupinfo [options] group1 [...] #包组查询

Ubuntu 软件管理

Debian 软件包通常为预编译的二进制格式的扩展名“.deb”,类似 rpm 文件,因此安装快速,无需编译软件。包文件包括特定功能或软件所必需的文件、元数据和指令

  • dpkg:package manager for Debian,类似于rpm, dpkg是基于Debian的系统的包管理器。可以安装,删除和构建软件包,但无法自动下载和安装软件包或其依赖项
  • apt:Advanced Packaging Tool,功能强大的软件管理工具,甚至可升级整个Ubuntu的系统,基于客户/服务器架构(c/s)

rhel 系列与 debian系列包管理对比

APT 工作原理

在服务器上先复制所有DEB包,然后用APT的分析工具genbasedir根据每个DEB 包的包头(Header)信息对所有的DEB包进行分析,并将该分析结果记录在文件夹base内的一个DEB 索引清单文件中,一旦APT 服务器内的DEB有所变动,要使用genbasedir产生新的DEB索引清单。

客户端在进行安装或升级时先要查询DEB索引清单,从而获知所有具有依赖关系的软件包,并一同下载到客户端以便安装。当客户端需要安装、升级或删除某个软件包时,客户端计算机取得DEB索引清单压缩文件后,会将其解压置放于 /var/cache/apt/,而客户端使用apt-get install或apt-get upgrade命令的时候,就会将这个文件夹内的数据和客户端计算机内的DEB数据库比对,知道哪些DEB已安装、未安装或是可以升级的。

dpkg 包管理器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
dpkg [<option> ...] <command>

#常用选项
-i|--install package.deb #安装包
--unpack package.deb #解包
-r|--remove packageName #删除包,不建议,不自动卸载依赖于它的包
-P|--purge packageName #删除包(包括配置文件)
-V|--verify packageName #检查包是否安装 rpm -q
--get-selections pattern #根据正则筛选包,并打出列表
--set-selections               #从标准输入里读出要选择的软件。
--clear-selections             #取消选中所有不必要的软件包。
--update-avail packageFile     #替换现有可安装的软件包信息。
--merge-avail packageFile     #把文件中的信息合并到系统中。
--clear-avail                 #清除现有的软件包信息。
--forget-old-unavail           #忘却已被卸载的不可安装的软件包。
-s|--status packageName #显示指定软件包的详细状态,类似于 rpm -qi
-p|--print-avail packageName #显示当前机器上所有可安装的包
-L|--listfiles packageName #列出属于指定软件包的文件,类似于 rpm -ql
-l|--list [pattern]       #列出当前己安装的包,类似于rpm -qa
-S|--search pattern         #根据文件查询是来自于哪个包,类似于 rpm -qf
-C|--audit [pattern]       #检查是否有软件包残损
--yet-to-unpack                #列出标记为待解压的软件包
--predep-package               #列出待解压的预依赖
--compare-vesions v1 - b #比较版本号
--force-help                   #显示本强制选项的帮助信息
-Dh|--debug=help               #显示有关出错调试的帮助信息
--info packageFile #列出包相关信息
-c packageFile #列出包内文件,类似于 rpm -qpl

apt 命令用法

Debian 使用 apt 工具集来管理包系统,apt-get 是其中一个常用的命令行工具,另外一款较为流行的命令行与 GUI 兼顾的工具是 aptitude ,之前最常用的 Linux 包管理命令都被分散在了 apt-get、apt-cache 和 apt-config 这三条命令中。

在 2014 年apt 命令发布第一个稳定版,Ubuntu 16.04 引入新特性之一便是 apt 命令,apt 命令解决了命令过于分散的问题,它包括 apt-get 命令出现以来使用最广泛的功能选项,以及 apt-cache 和 apt-config 命令中很少用到的功能。在使用 apt 命令时,用户不必再由 apt-get 转到 apt-cache 或 apt-config,提供管理软件包所需的必要选项

apt 相当于 apt-get、apt-cache 和 apt-config 中最常用命令选项的集合

apt 具有更精减但足够的命令选项,而且参数选项的组织方式更为有效。此外,启用的几个特性也非常有帮助。例如:可以在使用 apt 命令安装或删除程序时看到进度条,apt 还会在更新存储库数据库时提示用户可升级的软件包个数

apt 与 apt-get 有一些类似的命令选项,但它并不能完全向下兼容 apt-get 命令,也即可用 apt 替换部分apt-get 系列命令,但不是全部

image-20241125223759278

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apt [options] command
 
#options      
-h|--help   #显示帮助
-v|--version #显示版本
-y|--yes #自动回答yes
-q|--quiet #安静模式
   
#command
list       #根据名称列出软件包
search     #搜索软件包描述
show|info  #显示软件包细节
install   #安装软件包
remove     #移除软件包
autoremove #卸载所有自动安装且不再使用的软件包
update     #更新可用软件包列表,只更新索引文件,不具体更新软件
upgrade   #通过 安装/升级 软件来更新系统
full-upgrade #通过 卸载/安装/升级 来更新系统
edit-sources #编辑软件源信息文件