一 软件包(源码包和二进制包)
Linux软件包很多,几乎都是经过的 GPL 授权、免费开源(免费开源代码)。GPL,全称 General Public License,中文名称通用公开许可证 GPL 经过保护软件自由的协议 GPL 协议授权的软件必须开源,请猛击《开源协议》了解更多信息。
1 Linux源码包
源码包就是一大堆源代码程序,是由程序员按照特定的格式和语法编写出来的。计算机只能识别机器语言,即二进制语言,因此源代码包的安装需要翻译abcd翻译成二进制语言,通常被称为编译器。编译是指从源代码到直接由计算机(或虚拟机)执行的目标代码的翻译过程。编译器的功能是将源代码翻译成二进制代码,以便计算机能够识别和运行。
此外,由于源代码包的安装需要将源代码编译成二进制代码,因此安装时间较长。例如,每个人都应该在那里 Windows下安装过 QQ,QQ 功能多,程序比较大(有 70 MB左右),但由于不是以源码包的形式发布,而是编译后发布,只需几分钟(简单配置)即可成功安装。但是,如果我们以源码包安装的方式安装 Linux 中安装一个MySQL即使这个软件的压缩包只有数据库 23 MB左右,也需要 30 分钟左右(根据硬件配置略有差异)。
2Linux二进制包
二进制包,即源代码包成功编译后生成的包。由于二进制包在发布前已经完成了编译工作,用户安装软件的速度更快(与 Windows安装软件速度相等),安装过程中报错的概率大大降低。 二进制包是 Linux 默认软件安装包,所以二进制包也叫默认安装软件包。目前主要有以下几点 2 大主流的二进制包管理系统:
- RPM 包管理系统:功能强大,安装、升级、查询、卸载非常简单方便 Linux 发行版默认使用此机制作为软件安装的管理模式,如 Fedora、CentOS、SuSE 等。
- DPKG 包管理系统:由 Debian Linux 通过开发的包管理机制 DPKG 包,Debian Linux 软件包管理可以主要用于软件包管理 Debian 和 Ubuntu 中。
RPM 包括管理系统和 DPKG 管理系统的原理和形式相似,可以触类旁通
3两者异同
源码包一般包含多个文件,为方便发布,通常包装压缩源码包,Linux 最常用的包装压缩格式是tar.gz因此,源码包也被称为 Tarball。
Tarball 是 Linux 系统的包装工具可以包装和压缩源代码包。人们习惯于称最终的包装压缩文件为 Tarball 文件。
源码包需要我们自己去软件官方网站进行下载,包中通常包含以下内容:
- 源代码文件。
- 配置和检测程序(如 configure 或 config 等)。
- 软件安装说明和软件说明(如软件安装说明) INSTALL 或 README)。
一般来说,使用源码包安装软件有以下优点:
- 开源。如果您有足够的能力,可以修改源代码。
- 所需功能可自由选择。
- 因为软件是编译安装的,所以更适合自己的系统,更稳定,更高效。
- 卸载方便。
但与此同时,使用源码包安装软件也一些不足:
- 安装过程中有许多步骤,特别是在安装大型软件集合时(如 LAMP 环境建设)容易出现拼写错误。
- 编译时间长,安装时间长于二进制安装。
- 由于软件是编译安装的,一旦在安装过程中报错,新手很难解决。
与源码包相比,二进制包是软件发布时编译的软件包,因此安装速度远快于源码包(和 Windows 软件安装速度相等)。也正是因为通译,大家看不到软件的源代码。 使用 RMP 包装安装软件如下 2 点好处:
- 包管理系统简单,安装、升级、查询过几个命令来实现。
- 安装速度比源码包快得多。
同时,使用 RMP 包装软件有以下缺点:
- 编译后,无法看到源代码。
- 功能选择不如源码包灵活。
- 依赖性。有时我们会发现软件包的安装 a 需要先安装 b 和 c,而在安装 b 需要先安装 d 和 e。这需要先安装 d 和 e,再安装 b 和 c,最后可以安装 a。安装软件需要有一定的顺序,有时会非常依赖。
二RPM包统一命名规则
RPM 二进制包的命名应遵守统一的命名规则,用户可以通过名称直接获取此类包的版本、适用平台等信息。
RPM 二进制包命名的一般格式如下: 包名-版本号-发布次数-发行商-Linux合适的硬件平台-包扩展名称
例如,RPM 包的名称是httpd-2.2.15-15.el6.centos.1.i686.rpm
,其中:
- httped:软件包名。这里需要注意,httped 是包名,而 httpd-2.2.15-15.el6.centos.1.i686.rpm 通常称为包全名,包名和包全名不同,在某些方面 Linux 在命令中,有些命令(如包的安装和升级)使用包的全名,而有些命令(包的查询和卸载)使用包的名称,一不小心就会出错。
- 2.2.15:包的版本号,版本号的格式通常是
主版本号.次版本号.修正号
。 - 15:二进制包发布次数表示 RPM 包是几次编程生成的。
- el*:软件发行商,el6 说明这个包是由 Red Hat 适合公司发布 RHEL 6.x (Red Hat Enterprise Unux) 和 CentOS 6.x 上使用。
- centos:说明这个包适合CentOS 系统。
- i686:本包使用的硬件平台,目前 RPM 如表所示:
平台名称 | 适用于平台信息 |
---|---|
i386 | 386 以上的计算机都可以安装 |
i586 | 686 可安装上述计算机 |
i686 | 奔腾 II 上述计算机均可安装,目前全部 CPU 是奔腾 II 以上,所以这个软件版本大多是 |
x86_64 | 64 位 CPU 可以安装 |
noarch | 没有硬件限制 |
- rpm:RPM 包的扩展名称表明这是一个编译好的二进制包,可以使用 rpm 直接安装命令。另外,还有以 src.rpm 作为扩展名 RPM 包,说明是源代码包,需要安装生成源代码,然后编译生成 rpm 格式包最终可以使用 rpm 安装命令。Linux 系统不依赖于扩展名分区的文件类型,包括全名 .rpm 如果我们错了,扩展名是为系统管理员准备的 RPM 管理员很难知道这是一个扩展名 RPM 包。
三RPM包装、卸载和升级(rpm命令)详解
以安装 apache 程序为例
**rpm命令参数
-a:查询所有套件; -b<完成阶段><套件档> 或-t <完成阶段><套件档> :设置包装套件的完成阶段,并指定套件档的文件名称; -c:只列出组态配置文件,本参数需要配合"-l"参数使用; -d:只列出文本文件,本参数应配合"-l"参数使用; -e<套件档>或--erase<套件档>:删除指定套件; -f<文件> :查询具有指定文件的套件; -h或--has:套件安装时列出标记;
-i:显示套件的相关信息;
-i<套件档>或--install<套件档>:安装指定的套件档;
-l:显示套件的文件列表;
-p<套件档>+:查询指定的RPM套件档;
-q:使用询问模式,当遇到任何问题时,rpm指令会先询问用户;
-R:显示套件的关联性信息;
-s:显示文件状态,本参数需配合"-l"参数使用;
-U<套件档>或--upgrade<套件档>:升级指定的套件档;
-v:显示指令执行过程;
-vv:详细显示指令执行过程,便于排错。
1 RPM包默认安装路径
通常情况下,RPM 包采用系统默认的安装路径,所有安装文件会按照类别分散安装到表所示的目录中。RPM 包的默认安装路径是可以通过命令查询的。
装路径 | 含 义 |
---|---|
/etc/ | 配置文件安装目录 |
/usr/bin/ | 可执行的命令安装目录 |
/usr/lib/ | 程序所使用的函数库保存位置 |
/usr/share/doc/ | 基本的软件使用手册保存位置 |
/usr/share/man/ | 帮助文件保存位置 |
除此之外,RPM 包也支持手动指定安装路径,但此方式并不推荐。因为一旦手动指定安装路径,所有的安装文件会集中安装到指定位置,且系统中用来查询安装路径的命令也无法使用(需要进行手工配置才能被系统识别),得不偿失。 与 RPM 包不同,源码包的安装通常采用手动指定安装路径(习惯安装到 /usr/local/ 中)的方式。既然安装路径不同,同一 apache 程序的源码包和 RPM 包就可以安装到一台 Linux 服务器上(但同一时间只能开启一个,因为它们需要占用同一个 80 端口)。(实际情况中,一台服务器几乎不会同时包含两个 apache 程序)
2 RPM 包的安装
(1)命令格式
# 命令格式
[root@localhost ~]# rpm -ivh 包全名
!!一定是包全名。涉及到包全名的命令,一定要注意路径,可能软件包在光盘中,因此需提前做好设备的挂载工作。
(2)安装过程
# 使用此命令安装 apache 软件包
[root@localhost ~]# rpm -ivh \
/mnt/cdrom/Packages/httpd-2.2.15-15.el6.centos.1.i686.rpm
Preparing...
####################
[100%]
1:httpd
####################
[100%]
# 直到出现两个 100% 才是真正的安装成功,第一个 100% 仅表示完成了安装准备工作。
# 此命令还可以一次性安装多个软件包,仅需将包全名用空格分开即可
[root@localhost ~]# rpm -ivh a.rpm b.rpm c.rpm
如果还有其他安装要求(比如强制安装某软件而不管它是否有依赖性),可以通过以下选项进行调整:
- -nodeps:不检测依赖性安装。软件安装时会检测依赖性,确定所需的底层软件是否安装,如果没有安装则会报错。如果不管依赖性,想强制安装,则可以使用这个选项。注意,这样不检测依赖性安装的软件基本上是不能使用的,所以不建议这样做。
- -replacefiles:替换文件安装。如果要安装软件包,但是包中的部分文件已经存在,那么在正常安装时会报"某个文件已经存在"的错误,从而导致软件无法安装。使用这个选项可以忽略这个报错而覆盖安装。
- -replacepkgs:替换软件包安装。如果软件包已经安装,那么此选项可以把软件包重复安装一遍。
- -force:强制安装。不管是否已经安装,都重新安装。也就是 -replacefiles 和 -replacepkgs 的综合。
- -test:测试安装。不会实际安装,只是检测一下依赖性。
- -prefix:指定安装路径。为安装软件指定安装路径,而不使用默认安装路径。
安装完毕可以尝试启动。
3 RPM包的升级
[root@localhost ~]# rpm -Uvh 包全名
-U(大写):如果该软件没安装过则直接安装;若没安装则升级至最新版本。
[root@localhost ~]# rpm -Fvh 包全名
-F(大写):如果该软件没有安装,则不会安装,必须安装有较低版本才能升级。
4 RPM包的卸载
RPM 软件包的卸载要考虑包之间的依赖性。例如,我们先安装的 httpd 软件包,后安装 httpd 的功能模块 mod_ssl 包,那么在卸载时,就必须先卸载 mod_ssl,然后卸载 httpd,否则会报错。
# 命令
[root@localhost ~]# rpm -e 包名
# 如果卸载 RPM 软件不考虑依赖性,执行卸载命令会包依赖性错误
[root@localhost ~]# rpm -e httpd
error: Failed dependencies:
httpd-mmn = 20051115 is needed by (installed) mod_wsgi-3.2-1.el6.i686
httpd-mmn = 20051115 is needed by (installed) php-5.3.3-3.el6_2.8.i686
httpd-mmn = 20051115 is needed by (installed) mod_ssl-1:2.2.15-15.el6.
centos.1.i686
httpd-mmn = 20051115 is needed by (installed) mod_perl-2.0.4-10.el6.i686
httpd = 2.2.15-15.el6.centos.1 is needed by (installed) httpd-manual-2.2.
15-15.el6.centos.1 .noarch
httpd is needed by (installed) webalizer-2.21_02-3.3.el6.i686
httpd is needed by (installed) mod_ssl-1:2.2.15-15.el6.centos.1.i686
httpd=0:2.2.15-15.el6.centos.1 is needed by(installed)mod_ssl-1:2.2.15-15.el6.centos.1.i686
# RPM 软件包的卸载命令支持使用“-nocteps”选项,即可以不检测依赖性直接卸载,
# 但此方式不推荐大使用,因为此操作很可能导致其他软件也无法正常使用
5 rpm命令查询软件包
# 查询软件包是否安装
[root@localhost ~]# rpm -q 包名
# 查看 Linux 系统中是否安装 apache
[root@localhost ~]# rpm -q httpd
httpd-2.2.15-15.el6.centos.1.i686
# 查询系统中所有安装的软件包
[root@localhost ~]# rpm -qa | grep httpd
httpd-devel-2.2.15-15.el6.centos.1.i686
httpd-tools-2.2.15-15.el6.centos.1.i686
httpd-manual-2.2.15-15.el6.centos.1.noarch
httpd-2.2.15-15.el6.centos.1.i686
# 查询软件包的详细信息
[root@localhost ~]# rpm -qi 包名
# 想查看 apache 包的详细信息
[root@localhost ~]# rpm -qi httpd
Name : httpd Relocations:(not relocatable)
#包名
Version : 2.2.15 Vendor:CentOS
#版本和厂商
Release : 15.el6.centos.1 Build Date: 2012年02月14日星期二 06时27分1秒
#发行版本和建立时间
Install Date: 2013年01月07日星期一19时22分43秒
Build Host:
c6b18n2.bsys.dev.centos.org
#安装时间
Group : System Environment/Daemons Source RPM:
httpd-2.2.15-15.el6.centos.1.src.rpm
#组和源RPM包文件名
Size : 2896132 License: ASL 2.0
#软件包大小和许可协议
Signature :RSA/SHA1,2012年02月14日星期二 19时11分00秒,Key ID
0946fca2c105b9de
#数字签名
Packager:CentOS BuildSystem <http://bugs.centos.org>
URL : http://httpd.apache.org/
#厂商网址
Summary : Apache HTTP Server
#软件包说明
Description:
The Apache HTTP Server is a powerful, efficient, and extensible web server.
#描述
# 除此之外,还可以查询未安装软件包的详细信息
[root@localhost ~]# rpm -qip 包全名
# 注意,这里用的是包全名,且未安装的软件包需使用“绝对路径+包全名”的方式才能确定包。
# 命令查询软件包的文件列表
# rpm 软件包通常采用默认路径安装,各安装文件会分门别类安放在适当的目录文件下。
# 使用 rpm 命令可以查询到已安装软件包中包含的所有文件及各自安装路径
[root@localhost ~]# rpm -ql 包名
# 查看 apache 软件包中所有文件以及各自的安装位置
[root@localhost ~]# rpm -ql httpd
/etc/httpd
/etc/httpd/conf
/etc/httpd/conf.d
/etc/httpd/conf.d/README
/etc/httpd/conf.d/welcome.conf
/etc/httpd/conf/httpd.conf
/etc/httpd/conf/magic
………
# rpm 命令还可以查询未安装软件包中包含的所有文件以及打算安装的路径
[root@localhost ~]# rpm -qlp 包全名
# 由于软件包还未安装,因此需要使用“绝对路径+包全名”的方式才能确定包。
# 命令查询系统文件属于哪个RPM包
[root@localhost ~]# rpm -qf 系统文件名
# 注意,只有使用 RPM 包安装的文件才能使用该命令,手动方式建立的文件无法使用此命令
#查询 ls 命令所属的软件包
[root@localhost ~]# rpm -qf /bin/ls
coreutils-8.4-19.el6.i686
# 查询软件包的依赖关系
# 使用 rpm 命令安装 RPM 包,需考虑与其他 RPM 包的依赖关系。
[root@localhost ~]# rpm -qR 包名
[root@localhost ~]# rpm -qR httpd
/bin/bash
/bin/sh
/etc/mime.types
/usr/sbin/useradd
apr-util-ldap
chkconfig
config(httpd) = 2.2.15-15.el6.centos.1
httpd-tods = 2.2.15-15.el6.centos.1
initscripts >= 8.36
…省略部分输出…
# 在此命令的基础上增加 -p 选项,即可实现查找未安装软件包的依赖性。注意使用的也是“绝对路径+包全名”的方式
四 RPM包验证和数字证书(数字签名)
为了能够及时发现文件误删、误修改文件数据、恶意篡改文件内容等问题,Linux 提供了以下两种监控(检测)方式:
- RPM 包校验:其实就是将已安装文件和 /var/lib/rpm/ 目录下的数据库内容进行比较,确定文件内容是否被修改。
- RPM 包数字证书校验:用来校验 RPM 包本身是否被修改。
1 Linux RPM 包校验
[root@localhost ~]# rpm -Va
-Va 选项表示校验系统中已安装的所有软件包。
[root@localhost ~]# rpm -V 已安装的包名
-V 选项表示校验指定 RPM 包中的文件,是 verity 的首字母。
[root@localhost ~]# rpm -Vf 系统文件名
-Vf 选项表示校验某个系统文件是否被修改。
# 对文件进行修改后保存退出,再次使用 rpm -V 命令对 apache 软件包进行验证:
[root@localhost ~]# rpm -V httpd
S.5....T. c /etc/httpd/conf/httpd.conf
# S.5....T. c S.5....T. c /etc/httpd/conf/httpd.conf 表达的完整含义是:配置文件 httpd.conf 的大小、内容、修改时间被人为修改过。
可以看到,结果显示了文件被修改的信息。该信息可分为以下 3 部分:
1 最前面的 8 个字符(S.5....T)都属于验证信息,各字符的具体含义如下
- S:文件大小是否改变。
- M:文件的类型或文件的权限(rwx)是否改变。
- 5:文件MD5校验和是否改变(可以看成文件内容是否改变)。
- D:设备的主从代码是否改变。
- L:文件路径是否改变。
- U:文件的属主(所有者)是否改变。
- G:文件的属组是否改变。
- T:文件的修改时间是否改变。
- .:若相关项没发生改变,用 . 表示。
2 被修改文件类型,大致可分为以下几类
- c:配置文件(configuration file)。
- d:普通文档(documentation)。
- g:"鬼"文件(ghost file),很少见,就是该文件不应该被这个 RPM 包包含。
- l:授权文件(license file)。
- r:描述文件(read me)。
3 被修改文件所在绝对路径(包含文件名)。
注意,并非所有对文件做修改的行为都是恶意的。通常情况下,对配置文件做修改是正常的,比如说配置 apache 就要修改其配置文件,而如果验证信息提示对二进制文件做了修改,这就需要小心,除非是自己故意修改的。
2 RPM数字证书验证
RPM 包校验方法只能用来校验已安装的 RPM 包及其安装文件,如果 RPM 包本身就被动过手脚,此方法将无法解决问题,需要使用 RPM 数字证书验证方法。简单的理解,RPM 包校验其实就是将现有安装文件与最初使用 RPM 包安装时的初始文件进行对比,如果有改动则提示给用户,因此这种方式无法验证 RPM 包本身被修改的情况。
(1)数字证书
数字证书,又称数字签名,由软件开发商直接发布。Linux 系统安装数字证书后,若 RPM 包做了修改,此包携带的数字证书也会改变,将无法与系统成功匹配,软件无法安装。 可以将数字证书想象成自己的签名,是不能被模仿的(厂商的数字证书是唯一的),只有我认可的文件才会签名(只要是厂商发布的软件,都符合数字证书验证);如果文件被人修改了,那么签名就会变得不同(如果软件改变,数字证书就会改变,从而通不过验证)。
使用数字证书验证 RPM 包的方法具有如下 2 个特点:
- 必须找到原厂的公钥文件,然后才能进行安装。
- 安装 RPM 包会提取 RPM 包中的证书信息,然后和本机安装的原厂证书进行验证。如果验证通过,则允许安装;如果验证不通过,则不允许安装并发出警告。
# 数字证书存放目录
[root@192 ~]# ll /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
-rw-r--r--. 1 root root 1690 Apr 8 2020 /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
# 安装数字证书
[root@192 ~]# rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
# 数字证书安装完成后,可使用如下命令进行验证
[root@192 ~]# rpm -qa|grep gpg-pubkey
# 在装有数字证书的系统上安装 RPM 包时,系统会自动验证包的数字证书,验证通过则可以安装,反之将无法安装(系统会报错)。
数字证书本身也是一个 RPM 包,因此可以用 rpm 命令查询数字证书的详细信息,也可以将其卸载。
五 提取RPM包文件(cpio命令)详解
1 cpio命令
(1)介绍
cpio 命令用于从归档包中存入和读取文件,换句话说,cpio 命令可以从归档包中提取文件(或目录),也可以将文件(或目录)复制到归档包中。
归档包,也可称为文件库,其实就是 cpio 或 tar 格式的文件,该文件中包含其他文件以及一些相关信息(文件名、访问权限等)。归档包既可以是磁盘中的文件,也可以是磁带或管道。
cpio 命令可以看做是备份或还原命令,因为它可以将数据(文件)备份到 cpio 归档库,也可以利用 cpio 文档库对数据进行恢复。
使用 cpio 命令备份或恢复数据,需注意以下几点:
- 使用 cpio 备份数据时如果使用的是绝对路径,那么还原数据时会自动恢复到绝对路径下;同理,如果备份数据使用的是相对路径,那么数据会还原到相对路径下。
- cpio 命令无法自行指定备份(或还原)的文件,需要目标文件(或目录)的完整路径才能成功读取,因此此命令常与 find 命令配合使用。
- cpio 命令恢复数据时不会自动覆盖同名文件,也不会创建目录(直接解压到当前文件夹)。
(2)命令格式
# copy-out 模式,就是把数据备份到文件库中
[root@localhost ~]# cpio -o[vcB] > [文件丨设备]
-o:copy-out模式,备份;
-v:显示备份过程;
-c:使用较新的portable format存储方式;
-B:设定输入/输出块为 5120Bytes,而不是模式的 512Bytes;
# copy-in 模式,就是把数据从文件库中恢复
[root@localhost ~]# cpio -i[vcdu] < [文件|设备]
-i:copy-in 模式,还原;
-v:显示还原过程;
-c:较新的 portable format 存储方式;
-d:还原时自动新建目录;
-u:自动使用较新的文件覆盖较旧的文件;
# 复制模式,使用 -p 模式可以从某个目录读取所有文件,但并不将其备份到 cpio 库中,而是直接复制为其他文件
[root@localhost tmp]# cpio -p /tmp/test
#备份/boot/目录到/tmp/test/目录中
示例:
# 使用 cpio 备份数据
[root@localhost ~]#find /etc -print | cpio -ocvB > /root/etc.cpio
#利用find命令指定要备份/etc/目录,使用>导出到etc.cpio文件
[root@localhost ~]# II -h etc.cpio
-rw--r--r--.1 root root 21M 6月5 12:29 etc.cpio
#etc.cpio文件生成
# 使用 cpio 恢复之前备份的数据
[root@localhost ~]# cpio -idvcu < /root/etc.cpio
#还原etc的备份
#如果大家査看一下当前目录/root/,就会发现没有生成/etc/目录。这是因为备份时/etc/目录使用的是绝对路径,所以数据直接恢复到/etc/系统目录中,而没有生成在/root/etc/目录中
# 使用 -p 将 /boot/ 复制到 /test/boot 目录中
[root@localhost ~]# cd /tmp/
#进入/tmp/目录
[root@localhost tmp]#rm -rf*
#删除/tmp/目录中的所有数据
[root@localhost tmp]# mkdir test
#建立备份目录
[root@localhost tmp]# find /boot/ -print | cpio -p /tmp/test
#备份/boot/目录到/tmp/test/目录中
[root@localhost tmp]# ls test/boot
#在/tmp/test/目录中备份出了/boot/目录
2 使用 cpio 命令提取 RPM 包中指定文件
(1)介绍
在服务器使用过程,如果系统文件被误修改或误删除,可以考虑使用 cpio 命令提取出原 RPM 包中所需的系统文件,从而修复被误操作的源文件。
(2)命令格式
# RPM 包允许逐个提取包中文件
[root@localhost ~]# rpm2cpio 包全名|cpio -idv .文件绝对路径
# 该命令中,rpm2cpio 就是将 RPM 包转换为 cpio 格式的命令,通过 cpio 命令即可从 cpio 文件库中提取出指定文件。
(3)示例
假设我们不小心把 /bin/ls 命令删除了,通常有以下 2 种方式修复:
- 将 coreutils-8.4-19.el6.i686 包(包含 ls 命令的 RPM 包)通过 -force 选项再安装一遍;
- 使用 cpio 命令从 coreutils-8.4-19.el6.i686 包中提取出 /bin/ls 文件,然后将其复制到相应位置;
# 查询ls 命令隶属于那个 RPM 包
[root@localhost ~]# rpm -qf /bin/ls
coreutils-8.4-19.el6.i686
# 在此基础上,我们只需从此 RPM 包使用 cpio 命令提取出 ls 命令文件,然后将其复制到对应位置即可
[root@localhost ~]# mv /bin/ls /root/
#把/bin/ls命令移动到/root/目录下,造成误删除的假象
[root@localhost ~]# ls
-bash: ls: command not found
#这时执行ls命令,系统会报"命令没有找到"错误
[root@localhost ~]# rpm2cpio /mnt/cdrom/Packages/coreutils-8.4-19.el6.i686.rpm
|cpio -idv ./bin/ls
#提取ls命令文件到当前目录下
[root@localhost ~]# cp /root/bin/ls /bin/
#把提取出来的ls命令文件复制到/bin/目录下
[root@localhost ~]#ls
anaconda-ks.cfg bin inittab install.log install.log.syslog ls
#可以看到,ls命令又可以正常使用了
六 另一种 RPM 包——SRPM 源码包安装软件
1 介绍
SRPM 包中不再是经过编译的二进制文件,都是源代码文件。可以这样理解,SRPM 包是软件以源码形式发布后直接封装成 RPM 包的产物。
文件格式 | 文件名格式 | 直接安装与否 | 内含程序类型 | 可否修改参数并编译 |
---|---|---|---|---|
RPM | xxx.rpm | 可 | 已编译 | 不可 |
SRPM | xxx.src.rpm | 不可 | 未编译的源代码 | 可 |
SRPM 包的命名与 RPM 包基本类似,唯一区别在于 SRPM 包多了“src”标志,即 SRPM 包采用“包名-版本号-发布次数-发行商-src.rpm”的方式进行命名,比如“MySQL-5.5.29-2.el6.src.rpm”。
此外,SRPM 包是未经编译的源码包,无法直接用来安装软件,需要经过以下 2 步:
- 将 SRPM 包编译成二进制的 RPM 包;
- 使用编译完成的 RPM 包安装软件;
使用 SRPM 包安装软件(编译 SRPM 包)的方式有以下 2 种:
- 利用 rpmbuild 命令可以直接使用 SRPM 包安装软件,也可以先将 SRPM 包编译成 RPM 包,再使用 RPM 包安装软件;
- 利用 *.spec 文件可实现将 SRPM 包编译成 RPM 包,再使用 RPM 包安装软件;
2 rpmbuild 命令的安装
[root@localhost~]#rpm -ivh /mnt/cdroin/Packages/rpm-build-4.8.0-27.el6.i686.rpm
Preparing...
###################
[100%]
1:rpm-build
###################
[100%]
# rpmbuild 命令也是一个程序,但是这个程序不会默认安装
3 rpmbuild命令安装SRPM包
如果我们只想安装 SRPM 包,而不用修改源代码,那么直接使用 rpmbuild 命令即可
(1)命令格式
[root@localhost ~]# rpmbuild [选项] 包全名
-rebuild:编译 SRPM 包生成 RPM 二进制包;
-recompile:编译 SRPM 包,同时安装。
# SRPM 本质上仍属于 RPM 包,所以安装时仍需考虑包之间的依赖性,要先安装它的依赖包,才能正确安装。
(2)httpd示例
[root@localhost ~]# rpmbuild -rebuild httpd-2.2.15-5.el6.src.rpm
warning: InstallSourcePackage at: psm.c:244: Header V3 RSA/SHA256 Signature, key
ID fd431d51: NOKEY
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
# 警告为mockbuild用户不存在,使用root代替。这里不是报错,不用紧张
…省略部分输出…
Wrote: /root/rpmbuild/RPMS/i386/ httpd-2.2.15-5.el6.i386.rpm
Wrote: /root/rpmbuild/RPMS/i386/httpd-devel-2.2.15-5.el6.i386.rpm
Wrote: /root/rpmbuild/RPMS/noarch/httpd-manual-2.2.15-5.el6.noarch.rpm
Wrote: /root/rpmbuild/RPMS/i386/httpd-tools-2.2.15-5.el6.i386.rpm
Wrote: /root/rpmbuild/RPMS/i386/ mod_ssl-2.2.15-5.el6.i386.rpm
# 写入RPM包的位置,只要看到,就说明编译成功
Executing(%clean): /bin/sh -e/var/tmp/rpm-tmp.Wb8TKa
+ umask 022
+ cd/root/rpmbuild/BUILD
+ cd httpd-2.2.15
+ rm -rf /root/rpmbuild/BUILDROOT/httpd-2.2.15-5.el6.i386
+ exit 0
Executing(-clean): /bin/sh -e/var/tmp/rpm-tmp.3UBWql
+ umask 022
+ cd/root/rpmbuild/BUILD
+ rm-rf httpd-2.2.15
+ exit 0
# exit 0 是编译成功的标志,此编译过程产生的临时文件会自动删除。
# SRPM 包编译完成后,会在当前目录生成 rpmbuild 目录,整个编译过程生成的文件(软件包)都存在这里。
[root@localhost ~]# ls /root/rpmbuild/
BUILD RPMS SOURCES SPECS SRPMS
通过 ls 命令可以看到,rpmbuild 目录下有几个子目录,其各自保存的文件类别如表
文件名 | 文件内容 |
---|---|
BUILD | 编译过程中产生的数据保存位置 |
RPMS | 编译成功后,生成的 RPM 包保存位置 |
SOURCES | 从 SRPM 包中解压出来的源码包(*.tar.gz)保存位置 |
SPECS | 生成的设置文件的安装位置。第二种安装方法就是利用这个文件进行安装的 |
SRPMS | 放置 SRPM 包的位置 |
# 可以看到,编译好的 RPM 包保存在 /root/rpmbuild/RPMS/ 目录下
[root@localhost ~]#ll /root/rpmbuild/RPMS/i386/
-rw--r--r-- 1 root root 3039035 11月19 06:30 httpd-2.2.15-5.el6.i386.rpm
-rw--r--r-- 1 root root 154371 11月19 06:30 httpd-devel-2.2.15-5.el6.i386.rpm
-rw--r--r-- 1 root root 124403 11月19 06:30 httpd-tools-2.2.15-5.el6.i386.rpm
-rw--r--r-- 1 root root 383539 11月19 06:30 mod_ssl-2.2.15-5.el6.i386.rpm
如此,我们就得到可直接安装软件的 RPM 包。实际上,使用 rpmbuild命令编译 SRPM 包经历了以下 3 个过程:
- 先把 SRPM 包解开,得到源码包;
- 对源码包进行编译,生成二进制文件;
- 把二进制文件重新打包生成 RPM 包。
4 利用 *.spec 文件安装
想利用 .spec 文件安装软件,需先将 SRPM 包解开。我们可以使用 rpmbuild 命令解开 SRPM 包,但这里选择另一种方式,即使用 rpm -i
命令
[root@localhost ~]# rpm -i httpd-2.2.15-5.el6.src.rpm
-i 选项用于安装 rpm 包时表示安装,但对于 SRPM 包的安装来说,这里只会将 .src.rpm 包解开后将个文件放置在当前目录下的 rpmbuild 目录中,并不涉及安装操作。
通过此命令,也可以在当前目录下生成 rpmbuild 目录,,此 rpmbuild 目录中仅有 SOURCES 和 SPECS 两个子目录。其中,SOURCES 目录中放置的是源码,SPECS 目录中放置的是设置文件。
# 使用 SPECS 目录中的设置文件生成 RPM 包
[root@localhost ~]# rpmbuild -ba /root/rpmbuild/SPECS/httpd.spec
# -ba 选项的含义是编译,会同时生成 RPM 二进制包和 SRPM 源码包。这里还可以使用 -bb 选项用来仅生成 RPM 二进制包。
命令执行完成,会在 /root/rpmbuild/ 目录下生成 BUILD、RPMS、SOURCES、SPECS 和 SRPMS 目录,RPM 包放在 RPMS 目录中,SRPM 包生成在 SRPMS 目录中
七 重建RPM数据库
1 普通损坏介绍
并非所有的用户操作都“按常理出牌”,例如 RPM 包在升级过程被强行退出、RPM 包安装意外中断等误操作,都可能使 RPM 数据库出现故障,后果是当安装、删除、査询软件包时,请求无法执行
重建 RPM 数据库
# 删除当前系统中已损坏的RPM数据库,执行如下命令:
[root@localhost ~]# rm -f /var/lib/rpm/_db.*
# 重建 RPM 数据库,执行如下命令:
[root@localhost -]# rpm -rebuilddb # 这一步需花费一定时间才能完成
2 较严重情况
除了用户误操作导致 RPM 数据库崩溃,有些黑客入侵系统后,为避免系统管理员通过 RPM 包校验功能检测出问题,会更改 RPM 数据库。理论上,系统一旦被黑客“光顾”,则做的任何操作都将不可信。
对于这种情况,我们可以按照以下步骤对文件进行检测
# 对于要校验的文件或命令,找到它属于哪个软件包,如下命令所示:
[root@localhost ~]# rpm -qf/etc/rc.d/init.d/smb
samba-3.0.23c-2
# 使用 -dump 选项查看每个文件的信息,使用 grep 命令提取对应文件信息:
[root@localhost ~]# rpm -ql -dump samba|grep /etc/rc.d/init.d/smb
/etc/rc.d/init.d/smb 2087 1157165946 b1c26e5292157a83cadabe851bf9b2f9 0100755 root root 1 0 0X
# 此信息中:
“2087”表示 smb 文件最初的字符数
“b1c26e5292157a83cadabe851bf9b2f9”表示 smb 文件的 MD5 校验值
“0755 root root”表示文件权限及所有者、所属组。
# 查看实际的文件,通过对比文件大小,所有人、所属组、权限、MD5 校验值等数据,判断文件是否被改动过:
[root@localhost ~]# ls -l /etc/rc.d/init.d/smb
-rwxr-xr-x 1 root root 2087 Sep 2 2006/etc/rc.d/init.d/smb
[root@localhost ~]# md5sum /etc/rc.d/init.d/smb
b1c26e5292157a83cadabe851bf9b2f9 /etc/rc.d/init.d/smb
# 以上校验结果显示,系统的 /etc/rc.d/init.d/smb 文件的信息和通过 rpm-ql-dump Samba 命令获取的信息一致,因此可以断定此文件没有被入侵或更改。
如果确信 RPM 数据库遭到了修改,就要基于从光盘或者其他值得信赖的来源处获得的 Samba RPM 文件进行检査。
[root@localhost~]# rpm -ql --dump -p /mnt/cdrom/Fedora/RPMS/samba-3.0.23c-2.i386.rpm | grep /etc/rc.d/init.d/smb
warning: samba-3.0.23c-2.i386.rpm: Header V3 DSA signature: NOKEY, key ID 412a&62
/etc/rc.d/init.d/smb 2087 1157165946 b1c26e5292157a83cadabe851 bf9b2f9 0100755 root root 1 0 0 X
# 得到的结果如果和基于 RPM 数据库运行的命令结果不同,说明 RPM 数据库已被更改,就需要修正文件错误和系统漏洞,重建 RPM 数据库。
八 RPM包依赖性(含解决方案)
RPM 软件包(包含 SRPM 包)的依赖性主要体现在 RPM 包安装与卸载的过程中
# 如果采用最基础的方式(基础服务器方式)安装 Linux 系统,则 gcc 这个软件是没有安装的,需要自己手工安装。
# 当使用 rpm 命令安装 gcc 软件的 RPM 包,就会发生依赖性错误
[root@localhost ~]# rpm -ivh /mnt/cdrom/Packages/ gcc-4.4.6-4.el6.i686.rpm
error: Failed dependencies: <―依赖性错误
cloog-ppi >= 0.15 is needed by gcc-4.4.6-4.el6.i686
cpp = 4.4.6-4.el6 is needed by gcc-4.4.6-4.el6.i686
glibc-devel >= 2.2.90-12 is needed by gcc-4.4.6-4.el6.i686
# 报错信息提示我们,如果要安装 gcc,需要先安装 cloog-ppl、cpp 和 glibc-devel 三个软件,这体现的就是 RPM 包的依赖性。
除此之外,报错信息中还会明确给出各个依赖软件的版本要求:
">=":表示版本要大于或等于所显示版本;
"<=":表示版本要小于或等于所显示版本;
"=":表示版本要等于所显示版本;
Linux 系统中,RPM 包之间的依赖关系大致可分为以下 3 种:
- 树形依赖(A-B-C-D):要想安装软件 A,必须先安装 B,而安装 B 需要先安装 C…….解决此类型依赖的方法是从后往前安装,即先安装 D,再安装 C,然后安装 B,最后安装软件 A。
- 环形依赖(A-B-C-D-A):各个软件安装的依赖关系构成“环状”。解决此类型依赖的方法是用一条命令同时安装所有软件包,即使用
rpm -ivh 软件包A 软件包B ...
。 - 模型依赖:软件包的安装需要借助其他软件包的某些文件(比如库文件),解决模块依赖最直接的方式是通过 http://www.rpmfind.net 网站找到包含此文件的软件包,安装即可。