E

EdwardWong

V1

2022/12/12阅读:20主题:姹紫

Linux 软件安装

Linux下的软件众多,几乎都是GPLGeneral Public License)授权,中文名称“通用性公开许可证”。简单理解GPL就是一个保护软件自由的协议。

Linux软件包

Linux源码包

实际上源码包就是一大堆源代码程序,是由程序员按照特定的格式或语句编写出来的,需要编译将源代码翻译成二进制代码,让计算机识别并运行。

由于源码包的安装需要把源代码编译为二进制代码,因此安装时间较长。比如,大家应该都在 Windows下安装过 QQQQ 功能较多,程序相对较大(有 70 MB左右),但由于其并非是以源码包的形式发布,而是编译后才发布的,因此只需几分钟(经过简单的配置)即可安装成功。但如果我们以源码包安装的方式在 Linux 中安装一个 MySQL 数据库,即便此软件的压缩包仅有 23 MB左右,也需要 30 分钟左右的时间(根据硬件配置不同,略有差异)。

为了解决使用源码包安装方式的这些问题,Linux 软件包的安装出现了使用二进制包的安装方式.

Linux二进制包

二进制包,也就是源码包经过成功编译之后产生的包。由于二进制包在发布之前就已经完成了编译的工作,因此用户安装软件的速度较快(同 Windows下安装软件速度相当),且安装过程报错几率大大减小.

二进制包是 Linux 下默认的软件安装包,因此二进制包又被称为默认安装软件包。目前主要有以下 2 大主流的二进制包管理系统.

  • RPM包管理系统,很多Linux发行版默认使用此机制作为软件安装的管理方式,例如FedoraCentosSuSE等。

  • DPKG包管理系统。 由Debian Linux所开发的包管理机制,通过DKPG包,Debian Linux就可以进行软件包管理,主要应用于DebianUbuntu中。

源码包 vs RPM二进制包

源码包一般包含多个文件,为了方便发布,通常会将源码包做打包压缩处理Linux 中最常用的打包压缩格式为“tar.gz”,因此源码包又被称为 Tarball。

源码包需要我们自己去软件官方网站进行下载,包中通常包含以下内容:

  • 源代码文件
  • 配置和检测程序(configurationcongif等)
  • 软件安装说明和软件说明(INSTALLREADME

总的来说,使用源码包安装软件具有以下几点好处:

  • 开源。如果你有足够的能力,则可以修改源代码。

  • 可以自由选择所需的功能。

  • 因为软件是编译安装的,所以更加适合自己的系统,更加稳定,效率也更高。

  • 卸载方便

但是也有以下不足:

  • 安装过程步骤较多,尤其是在安装较大的软件集合时(如 LAMP 环境搭建),容易出现拼写错误。

  • 编译时间较长,所以安装时间比二进制安装要长

  • 因为软件是编译安装的,所以在安装过程中一旦报错,新手很难解决。

相比源码包,二进制包是在软件发布时已经进行过编译的软件包,所以安装速度比源码包快得多(和 Windows 下软件安装速度相当)。也正是因为已经进行编译,大家无法看到软件的源代码。

使用 RMP 包安装软件具有以下 2点好处:

  • 包管理系统简单,只通过几个命令就可以实现包的安装、升级、査询和卸载。

  • 安装速度比源码包安装快得多。

与此同时,使用 RMP 包安装软件有如下不 足:

  • 经过编译,不能在看到源代码

  • 功能选择不如源码包灵活。

  • 依赖性。有时我们会发现,在安装软件包 a 时需要先安装 bc,而在安装 b 时需要先安装 de。这就需要先安装 de,再安装 bc,最后才能安装 a

Linux 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全包名

  • 2.2.15: 包的版本号,版本号的格式通常为主版本号.次版本号.修正号

  • 15: 二进制包发布的次数,表示此 RPM 包是第几次编程生成的。

  • el*: 软件发行商,el6表示此包是由Red Hat公司发布,适合在RHEL 6.xCentOS 6.x

  • centos: 表示此包适用于CentOS系统

  • i686: 表示此包使用的硬件平台。

  • rpmRPM扩展包,表明这是编译好的二进制包,可以使用RPM命令直接安装,此外,还有src.rpm作为拓展名的RPM包,这表明是源代码包。需要安装生成源码,然后对其编译生成rpm格式的包,最后使用rpm命令安装。

Linux RPM包安装、卸载和升级

RPM包默认安装路径

以安装apache程序为例,介绍使用二进制包安装的过程。

通常情况下,RPM包采用系统默认的安装路径,所有安装文件会按照类别分散安装到下表所示的目录中。

RPM 包的默认安装路径是可以通过命令查询的。

RPM 包不同,源码包的安装通常采用手动指定安装路径(习惯安装到 /usr/local/ 中)的方式。既然安装路径不同,同一 apache 程序的源码包和 RPM 包就可以安装到一台 Linux 服务器上(但同一时间只能开启一个,因为它们需要占用同一个 80 端口)。

实际情况中,一台服务器几乎不会同时包含两个 apache 程序,管理员不好管理,还会占用过多的服务器磁盘空间。

RPM包安装

安装RPM包的命令格式:

rpm -ivh 包全名

这个地方一定是包全名,涉及到包全名的命令,一定要注意路径,可能软件包在光盘中,因此需要提前做好设备的挂载工作

此命令中各选项参数的含义为:

  • -i:安装(install);

  • -v:显示更详细的信息(verbose);

  • -h:打印 #,显示安装进度(hash);

[root@localhost ~]# rpm -ivh \  //(\表示在下一行继续书写)
/mnt/cdrom/Packages/httpd-2.2.15-15.el6.centos.1.i686.rpm
Preparing...
####################
[100%]
1:httpd
####################
[100%]

注意,直到出现两个 100% 才是真正的安装成功,第一个 100% 仅表示完成了安装准备工作。

此命令还可以一次性安装多个软件包,仅需将包全名用空格分开即可.

rpm -ivh a.rpm b.rpm c.rpm

如果还有其他安装要求(比如强制安装某软件而不管它是否有依赖性),可以通过以下选项进行调整:

  • -nodeps: 不检测依赖性安装。软件安装时会检测依赖性,确定所需的底层软件是否安装,如果没有安装则会报错。如果不管依赖性,想强制安装,则可以使用这个选项。注意,这样不检测依赖性安装的软件基本上是不能使用的,所以不建议这样做。

  • replacefiles: 替换文件安装。如果要安装软件包,但是包中的部分文件已经存在,那么在正常安装时会报"某个文件已经存在"的错误,从而导致软件无法安装。使用这个选项可以忽略这个报错而覆盖安装。

  • replacepkgs: 替换软件包安装。如果软件包已经安装,那么此选项可以把软件包重复安装一遍。

  • -force: 强制安装。不管是否已经安装,都重新安装。也就是 -replacefiles-replacepkgs 的综合

  • -test: 测试安装。不会实际安装,只是检测一下依赖性。

  • -prefix: 指定安装路径。为安装软件指定安装路径,而不使用默认安装路径

apache服务安装完成后,可以尝试启动:

service 服务名 start|stop|restart|status

  • start:启动服务;

  • stop: 停止服务

  • restart: 重启服务

  • status: 查看服务状态

service httpd start #启动apache服务

服务启动后,可以查看端口号80是否出现:

[root@localhost ~]# netstat -tlun | grep 80
tcp 0 0 :::80:::* LISTEN

RPM包的升级

rpm -Uvh 包全名

  • -U选项的含义是:如果该软件没安装过则直接安装;若没安装则升级至最新版本

rpm -Fvh 包全名

  • -F选项的含义是:如果该软件没有安装,则不会安装,如果安装有较低版本才升级。

RPM包的卸载

rpm -e 包名 //卸载软件包

RPM 软件包的卸载要考虑包之间的依赖性。 例如,我们先安装的 httpd 软件包,后安装 httpd 的功能模块 mod_ssl 包,那么在卸载时,就必须先卸载 mod_ssl,然后卸载 httpd,否则会报错。

[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命令查询软件包

rpm 命令还可用来对 RPM 软件包做查询操作.

  • 查询软件包是否已安装
  • 查询系统中所有已安装的软件包;
  • 查看软件包的详细信息
  • 查询软件包的文件列表
  • 查询某系统文件具体属于哪个 RPM 包。

使用rpm做查询命令的格式:

rpm 选项 查询对象

rpm -q 查询软件包是否安装

rpm -q 包名

-q 表示查询,是query首字母

[root@localhost ~]# rpm -q httpd
httpd-2.2.15-15.el6.centos.1.i686

注意这里使用的是包名,而不是包全名。因为已安装的软件包只需给出包名,系统就可以成功识别(使用包全名反而无法识别)

rpm -qa 查询系统中所有安装的软件包

[root@localhost ~]# rpm -qa
libsamplerate-0.1.7-2.1.el6.i686
startup-notification-0.10-2.1.el6.i686
gnome-themes-2.28.1-6.el6.noarch
fontpackages-filesystem-1.41-1.1.el6.noarch
gdm-libs-2.30.4-33.el6_2.i686
gstreamer-0.10.29-1.el6.i686
redhat-lsb-graphics-4.0-3.el6.centos.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

rpm -qi查询软件包的详细信息

通过 rpm 命令可以查询软件包的详细信息,命令格式如下:

[root@localhost ~]# rpm -qi 包名 //查看已安装的软件包

-i选项表示查询软件信息,是information首字母

[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.
#描述

除此之外,还可以查询未安装软件包的详细信息,命令格式为

rpm -qip 包全名

-p选项表示查询未安装的软件包,是package的首字母

这里用的是包全名,且未安装的软件包需使用“绝对路径+包全名”的方式才能确定包。

rpm -ql查询软件包的文件列表

rpm 软件包通常采用默认路径安装,各安装文件会分门别类安放在适当的目录文件下。使用 rpm 命令可以查询到已安装软件包中包含的所有文件及各自安装路径

rpm -ql 包名

  • -l选项表示列出软件包所有文件的安装目录。

例如,查看 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 命令还可以查询未安装软件包中包含的所有文件以及打算安装的路径,命令格式如下:

rpm -qlp 包全名

-p选项表示查询未安装的软件包信息,是 package 的首字母。

由于软件包还未安装,因此需要使用绝对路径+包全名的方式才能确定包。

比如,我们想查看 bing 软件包(未安装,绝对路径为:/mnt/cdrom/Packages/bind-9.8.2-0.10.rc1.el6.i686.rpm)中的所有文件及各自打算安装的位置,可以执行如下命令:

[root@localhost ~]# rpm -qlp /mnt/cdrom/Packages/bind-9.8.2-0.10.rc1.el6.i686.rpm
/etc/NetworkManager/dispatcher.d/13-named
/etc/logrotate.d/named
/etc/named
/etc/named.conf
/etc/named.iscdlv.key
/etc/named.rfc1912.zones
…省略部分输出…

rpm -qf查询系统文件属于哪个RPM

rpm -ql 命令是通过软件包查询所含文件的安装路径,rpm 还支持反向查询,即查询某系统文件所属哪个 RPM 软件包。其命令格式如下:

[root@localhost ~]# rpm -qf 系统文件名

-f 选项的含义是查询系统文件所属哪个软件包,是 file 的首字母。

例如,查询 ls 命令所属的软件包,可以执行如下命令:

[root@localhost ~]# rpm -qf /bin/ls
coreutils-8.4-19.el6.i686

rpm -qR查询软件包的依赖关系

rpm -qR 包名

-R查询软件包的依赖性,是requires的首字母

使用 rpm 命令安装 RPM 包,需考虑与其他 RPM 包的依赖关系。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 选项,即可实现查找未安装软件包的依赖性。

[root@localhost ~]# rpm -qRp /mnt/cdrom/Packages/bind-9.8.2-0.10.rc1.el6.i686.rpm
/bin/bash
/bin/sh
bind-libs = 32:9.8.2-0.10.rc1.el6
chkconfig
chkconfig
config(bind) = 32:9.8.2-0.10.rc1.el6
grep
libbind9.so.80
libc.so.6
libc.so.6(GLIBC_2.0)
libc.so.6(GLIBC_2.1)
…省略部分输出…

Linux RPM包验证和数字证书

执行 rpm -qa 命令可以看到,Linux 系统中装有大量的 RPM 包,且每个包都含有大量的安装文件。因此,为了能够及时发现文件误删、误修改文件数据、恶意篡改文件内容等问题,Linux 提供了以下两种监控(检测)方式:

  • RPM包验证: 其实就是将已安装文件和 /var/lib/rpm/ 目录下的数据库内容进行比较,确定文件内容是否被修改。

  • RPM包数字证书校验:用来校验 RPM 包本身是否被修改。

Linux RPM包校验

RPM 包校验可用来判断已安装的软件包(或文件)是否被修改,此方式可使用的命令格式分为以下 3 种。

rpm -Va -Va选项表示校验系统中已安装的所有软件包

rpm -V 已安装的包名 -V 选项表示校验指定 RPM 包中的文件,是 verity 的首字母。

rpm -Vf 系统文件名 -Vf校验某个系统文件是否被修改。

例如我们校验 apache 软件包中所有的安装文件是否被修改,可执行如下命令:

rpm -V httpd

可以看到,执行后无任何提示信息,表明所有用 apache 软件包安装的文件均未改动过,还和从原软件包安装的文件一样.

接下来尝试对 apache 的配置文件 /etc/httpd/conf/httpd.conf 做适当修改,修改格式如下

[root@localhost ~]#vim /etc/httpd/conf/httpd.conf
...省略部分内容...
Directorylndex index.html index.html.var index.php
#这句话是定义apache可以识别的默认网页文件名。在后面加入了index.php
#这句话大概有400行左右
…省略部分内容...

对文件进行修改后保存退出,再次使用 rpm -V 命令对 apache 软件包进行验证:

[root@localhost ~]# rpm -V httpd
S.5....T. c /etc/httpd/conf/httpd.conf
  1. 最前面8个字符(S.5....T.)属于验证信息,各字符的具体含义如下:
  • S:文件大小是否改变。

  • M: 文件的类型或文件的权限(rwx)是否改变。

  • 5: 文件MD5校验和是否改变(可以看成文件内容是否改变)。

  • D: 设备的主从代码是否会改变

  • L: 文件路径是否改变

  • U: 文件的所有者是否改变

  • G: 文件的属组是否改变

  • T: 文件的修改时间是否改变

  • .: 若相关选项没有改变,用.改变

  1. 被修改文件类型,大致可分为以下几类:
  • c:配置文件(configuration file)

  • d:普通文件(documentation)

  • g鬼文件(ghost file)

  • l: 授权文件(license file)

  • r: 描述文件(readme)

  1. 被修改文件所在绝对路径(包含文件名)

由此,S.5....T. c S.5....T. c /etc/httpd/conf/httpd.conf 表达的完整含义是:配置文件 httpd.conf 的大小、内容、修改时间被人为修改过。

注意,并非所有对文件做修改的行为都是恶意的。通常情况下,对配置文件做修改是正常的,比如说配置 apache 就要修改其配置文件,而如果验证信息提示对二进制文件做了修改,这就需要小心,除非是自己故意修改的

RPM 包校验其实就是将现有安装文件与最初使用 RPM 包安装时的初始文件进行对比,如果有改动则提示给用户,因此这种方式无法验证 RPM 包本身被修改的情况。

Linux RPM数字证书验证

RPM包校验只能用来校验已安装的RPM包及其安装文件,如果RPM包本身就被动过手脚,此方法将无法解决问题,需要使用RPM数字证书验证方法

数字证书,又称数字签名,由软件开发商直接发布Linux 系统安装数字证书后,RPM 包做了修改,此包携带的数字证书也会改变,将无法与系统成功匹配,软件无法安装

可以将数字证书想象成自己的签名,是不能被模仿的(厂商的数字证书是唯一的),只有我认可的文件才会签名(只要是厂商发布的软件,都符合数字证书验证);如果我的文件被人修改了,那么我的签名就会变得不同(如果软件改变,数字证书就会改变,从而通不过验证。当然,现实中人的手工签名不会直接改变,所以数字证书比手工签名还要可靠)

使用数字证书验证 RPM 包的方法具有如下 2 个特点:

  • 必须找到原厂的公钥文件,然后才能进行安装。

  • 安装 RPM 包会提取 RPM 包中的证书信息,然后和本机安装的原厂证书进行验证。如果验证通过,则允许安装;如果验证不通过,则不允许安装并发出警告。

数字证书默认会放到系统中/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6位置处,通过以下命令也可验证:

[root@localhost ~]# rpm --import /efc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
--import表示导入数字证书

数字证书安装完成后,可使用如下命令进行验证

[root@localhost ~]# rpm -qa|grep gpg-pubkey
gpg-pubkey-c105b9de-4e0fd3a3

可以看到,数字证书已成功安装。在装有数字证书的系统上安装 RPM 包时,系统会自动验证包的数字证书,验证通过则可以安装,反之将无法安装(系统会报错)。

数字证书本身也是一个 RPM,因此可以用 rpm 命令查询数字证书的详细信息,也可以将其卸载

[root@localhost ~]# rpm -qi gpg-pubkey-c105b9de-4e0fd3a3
#查询数字证书包的详细信息
Name : gpg-pubkey
Relocations: (not relocatable)
Version : c105b9de Vendor: (none)
Release : 4e0fd3a3 Build Date: 2012年11月12日 星期一 23时05分20秒
Install Date: 2012年11月12日星期一23时05分20秒 Build Host: local host
Group : Public Keys
Source RPM: (none)
Size : 0
License: pubkey
…省略部分输出…
-----END PGP PUBLIC KEY BLOCK----

卸载数字证书可以使用 -e 选项,命令如下:

rpm -e gpg-pubkey-c105b9de-4ead3a3

Linux提取RPM包文件(cpio命令)详解

cpio 命令用于从归档包中存入和读取文件,换句话说,cpio 命令可以从归档包中提取文件(或目录),也可以将文件(或目录)复制到归档包中。

cpio 命令可以看做是备份或还原命令,因为它可以将数据(文件)备份到 cpio 归档库,也可以利用 cpio 文档库对数据进行恢复。

使用 cpio 命令备份或恢复数据,需注意以下几点:

  • 使用 cpio备份数据时如果使用的是绝对路径,那么还原数据时会自动恢复到绝对路径下;同理,如果备份数据使用的是相对路径,那么数据会还原到相对路径下。

  • cpio 命令无法自行指定备份(或还原)的文件,需要目标文件(或目录)的完整路径才能成功读取,因此此命令常与 find 命令配合使用。

  • cpio 命令恢复数据时不会自动覆盖同名文件,也不会创建目录(直接解压到当前文件夹)

备份与还原

  1. -o模式,指的是copy-out模式,就是把数据备份到文件库中,命令格式:

cpio -o[vcB] >[文件|设备]

  • -ocopy-out模式,备份;

  • -v:显示备份过程

  • -c: 使用较新的portable format存储方式

  • -B: 设定输入/输出块为5120Bytes,而不是模式的512Bytes

比如,使用 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文件生成
  1. -i模式:指的是copy-in模式,就是把数据从文件库中恢复。

[root@localhost ~]# cpio -i[vcdu] < [文件|设备]

  • -i: copy-in模式,还原

  • -v: 显示还原过程

  • -c:较新的portable format存储方法

  • -d: 还原时自动新建目录

  • -u: 自动使用较新的文件覆盖较旧的文件

比如,使用 cpio 恢复之前备份的数据,命令如下:

[root@localhost ~]# cpio -idvcu < /root/etc.cpio
#还原etc的备份
#如果大家査看一下当前目录/root/,就会发现没有生成/etc/目录。**这是因为备份时/etc/目录使用的是绝对路径,所以数据直接恢复到/etc/系统目录中,而没有生成在/root/etc/目录中**
  1. -p模式:指的是复制模式。使用 -p 模式可以从某个目录读取所有文件,但并不将其备份到 cpio 库中,而是直接复制为其他文件.

例如,使用 -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/目录

使用 cpio 命令提取 RPM 包中指定文件

在服务器使用过程,如果系统文件被误修改或误删除,可以考虑使用 cpio 命令提取出原 RPM 包中所需的系统文件,从而修复被误操作的源文件

rpm2cpio 包全名|cpio -idv .文件绝对路径

该命令中,rpm2cpio 就是将 RPM 包转换为 cpio 格式的命令,通过 cpio 命令即可从 cpio 文件库中提取出指定文件。

举个例子,假设我们不小心把 /bin/ls 命令删除了,通常有以下 2 种方式修复:

  • coreutils-8.4-19.el6.i686 包(包含 ls 命令的 RPM 包)通过 -force 选项再安装一遍;

  • 使用 cpio 命令从 coreutils-8.4-19.el6.i686 包中提取出 /bin/ls 文件,然后将其复制到相应位置;

如何知道 ls 命令隶属于那个 RPM 包呢?很简单,使用 rpm -qf 命令即可,如下所示:

[root@localhost ~]# rpm -qf /bin/ls
coreutils-8.4-19.el6.i686
#查看ls文件属于哪个软件包

我们只需从此 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命令又可以正常使用了

Linux SRPM源码包安装

SRPM 包,比 RPM 包多了一个“S”,是“Source”的首字母,所以 SRPM 可直译为“源代码形式的 RPM 包”。也就是说,**SRPM 包中不再是经过编译的二进制文件,都是源代码文件**。可以这样理解,SRPM 包是软件以源码形式发布后直接封装成 RPM 包的产物。

SRPM 包的命名与 RPM 包基本类似,唯一区别在于 SRPM 包多了“src”标志,即 SRPM 包采用“包名-版本号-发布次数-发行商-src.rpm”的方式进行命名,比如“MySQL-5.5.29-2.el6.src.rpm”

SRPM 包是未经编译的源码包,无法直接用来安装软件,需要经过以下 2 步:

  • SRPM 包编译成二进制的 RPM 包;

  • 使用编译完成的 RPM 包安装软件;

以安装 apache 为例,使用 SRPM 包安装软件(编译 SRPM 包)的方式有以下 2 种:

  1. 利用 rpmbuild 命令可以直接使用 SRPM 包安装软件,也可以先将 SRPM 包编译成 RPM 包,再使用 RPM 包安装软件;

  2. 利用 *.spec 文件可实现将 SRPM 包编译成 RPM 包,再使用 RPM 包安装软件;

rpmbuild方式

rpmbuild命令安装

rpmbuild 命令也是一个程序,但是这个程序不会默认安装,所以要想使用 rpmbuild 命令就必须提前安装。这里我们使用 rpm 命令来安装 rpmbuild 命令.

[root@localhost~]#rpm -ivh /mnt/cdroin/Packages/rpm-build-4.8.0-27.el6.i686.rpm
Preparing...
###################
[100%]
1:rpm-build
###################
[100%]

rpmbuild命令安装SRPM

如果我们只想安装 SRPM 包,而不用修改源代码,那么直接使用 rpmbuild 命令即可。使用 rpmbuild 安装 SRPM 包的命令格式如下:

rpmbuild [选项] 包全名

  • rebuild: 编译SRPM包生成RPM二进制包

  • recompile: 编译 SRPM 包,同时安装。

需要注意的是,SRPM 本质上仍属于 RPM 包,所以安装时仍需考虑包之间的依赖性,要先安装它的依赖包,才能正确安装

[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

编译好的 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 个过程:

  1. 先把SPRM包解开,得到源码包

  2. 对源码包进行编译,生成二进制文件

  3. 把二进制文件重新打包生成RPM包。

利用*.spec文件安装

想利用 .spec 文件安装软件,需先将 SRPM 包解开。当然,我们可以使用 rpmbuild 命令解开 SRPM 包,但这里选择另一种方式,即使用 rpm -i 命令,如下所示:

rpm -i httpd-2.2.15-5.el6.src.rpm

-i 选项用于安装 rpm 包时表示安装,但对于 SRPM 包的安装来说,这里只会将 .src.rpm 包解开后将个文件放置在当前目录下的 rpmbuild 目录中。

通过此命令,也可以在当前目录下生成 rpmbuild 目录,此 rpmbuild 目录中仅有 SOURCESSPECS 两个子目录。其中,SOURCES 目录中放置的是源码,SPECS 目录中放置的是设置文件。

接下来使用 SPECS 目录中的设置文件生成 RPM 包,命令如下:

rpmbuild -ba /root/rpmbuild/SPECS/httpd.spec

其中,-ba 选项的含义是编译,会同时生成 RPM 二进制包和 SRPM 源码包。这里还可以使用 -bb 选项用来仅生成 RPM 二进制包。

命令执行完成,会在 /root/rpmbuild/ 目录下生成 BUILDRPMSSOURCESSPECSSRPMS 目录,RPM 包放在 RPMS 目录中,SRPM 包生成在 SRPMS 目录中。

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-pplcppglibc-devel 三个软件,这体现的就是 RPM 包的依赖性。

除此之外,报错信息中还会明确给出各个依赖软件的版本要求">=":表示版本要大于或等于所显示版本; "<=":表示版本要小于或等于所显示版本; "=":表示版本要等于所显示版本;

Linux系统中,RPM包之间的依赖关系大致分为以下3种:

  1. 树形依赖(A-B-C-D):要想安装软件 A,必须先安装 B,而安装 B 需要先安装 C…….解决此类型依赖的方法是从后往前安装,即先安装 D,再安装 C,然后安装 B,最后安装软件 A

  2. 环形依赖(A-B-C-D-A):各个软件安装的依赖关系构成“环状”。**解决此类型依赖的方法是用一条命令同时安装所有软件包,即使用 rpm -ivh 软件包A 软件包B ...**。

  3. 模型依赖:软件包的安装需要借助其他软件包的某些文件(比如库文件),解决模块依赖最直接的方式是通过 http://www.rpmfind.net 网站找到包含此文件的软件包,安装即可。

yum安装软件

之前介绍了SPRMRPM二进制包安装软件,都需要手动解决包之间依赖性的问题。yum可以自动安装软件包并且解决包之间的依赖关系。yum是一个软件包管理软件,就好比windows系统上的360软件管家实现软件的一键安装、升级和卸载等工作。

yum的安装

可以通过rpm安装,查看yum是否安装rpm -qa |grep yum

yum-metadata-parser-1.1.2-16.el6.i686
yum-3.2.29-30.el6.centos.noarch
yum-utils-1.1.30-14.el6.noarch
yum-plugin-fastestmirror-1.1.30-14.el6.noarch
yum-plugin-security-1.1.30-14.el6.noarch

使用yum安装软件包之前,需指定好yum下载RPM包的位置,此位置称为yum源。

yum

yum 安装软件时至少需要一个 yum。**yum 源既可以使用网络 yum 源,也可以将本地光盘作为 yum 源**。接下来就给大家介绍这两种 yum 源的搭建方式。

网络 yum 源配置文件位于 /etc/yum.repos.d/ 目录下,文件扩展名为"*.repo"(只要扩展名为 "*.repo" 的文件都是 yum 源的配置文件)

[root@localhost ~]# ls /etc/yum.repos.d/
CentOS-Base.repo
CentOS-Media.repo
CentOS-Debuginfo.repo.bak
CentOS-Vault.repo

可以看到,该目录下有 4yum 配置文件,通常情况下 CentOS-Base.repo 文件生效,其内容如下:

[root@localhost yum.repos.d]# vim /etc/yum.repos.d/ CentOS-Base.repo
[base]
name=CentOS-$releasever - Base
mirrorlist=http://mirrorlist.centos.org/? release= $releasever&arch=$basearch&repo=os
baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
…省略部分输出…

此文件中含有 5yum 源容器,这里只列出了 base 容器,其他容器和 base 容器类似。base 容器中各参数的含义分别为:

  • [base]: 容器名称,一定要放在[]

  • name: 容器说明,可以自己随便写

  • mirrorlist:镜像站点,这个可以注释掉

  • baseurl:我们的 yum 源服务器的地址。默认是 CentOS 官方的 yum 源服务器,是可以使用的。如果你觉得慢,则可以改成你喜欢的 yum 源地址

  • enabled:此容器是否生效,如果不写或写成 enabled 则表示此容器生效,写成 enable=0 则表示此容器不生效。

  • gpgcheck: 如果为 1 则表示 RPM 的数字证书生效;如果为 0 则表示 RPM 的数字证书不生效

  • gpgkey数字证书的公钥文件保存位置。不用修改

本地yum

在无法联网的情况下,yum 可以考虑用本地光盘(或安装映像文件)作为 yum 源。

Linux 系统安装映像文件中就含有常用的 RPM 包,我们可以使用压缩文件打开映像文件iso文件),进入其 Packages 子目录,如图 1 所示:

可以看到,该子目录下含有几乎所有常用的 RPM 包,因此使用系统安装映像作为本地 yum 源没有任何问题.

/etc/yum.repos.d/ 目录下有一个 CentOS-Media.repo 文件,此文件就是以本地光盘作为 yum 源的模板文件,只需进行简单的修改即可,步骤如下:

  1. 放入 CentOS 安装光盘,并挂载光盘到指定位置.
[root@localhost ~]# mkdir /mnt/cdrom
#创建cdrom目录,作为光盘的挂载点
[root@localhost ~]# mount /dev/cdrom /mnt/cdrom/
mount: block device/dev/srO is write-protected, mounting read-only
#挂载光盘到/mnt/cdrom目录下
  1. 修改其他几个 yum 源配置文件的扩展名,让它们失效,因为只有扩展名是"*.repo"的文件才能作为 yum 源配置文件。当然可以删除其他几个 yum 源配置文件,但是如果删除了,当又想用网络作为 yum 源时,就没有了参考文件,所以最好还是修改扩展名。
[root@localhost ~]# cd /etc/yum.repos.d/
[root@localhost yum.repos.d]# mv CentOS-Base.repo CentOS-Base.repo.bak
[root@localhost yum.repos.d]#mv CentOS-Debuginfo.repo CentOS-Debuginfo.repo.bak
[root@localhost yum.repos.d]# mv CentOS-Vault.repo CentOS-Vault.repo.bak
  1. 修改光盘 yum 源配置文件 CentOS-Media.repo
[root@localhost yum.repos.d]# vim CentOS-Media.repo
[c6-media]
name=CentOS-$releasever - Media
baseurl=file:///mnt/cdrom
#地址为你自己的光盘挂载地址
#file:///media/cdrom/
#file:///media/cdrecorder/
#注释这两个的不存在地址
gpgcheck=1
enabled=1
#把enabled=0改为enabled=1, 让这个yum源配置文件生效
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6

这样本地的yum源就配置完成了。

yum命令

yum查询命令

使用 yum 对软件包执行查询操作,常用命令可分为以下几种:

  • yum list: 查询所有已安装和可安装的软件包
[root@localhost yum.repos.d]# yum list
#查询所有可用软件包列表
Installed Packages
#已经安装的软件包
ConsdeKit.i686 0.4.1-3.el6
@anaconda-CentOS-201207051201 J386/6.3
ConsdeKit-libs.i686 0.4.1-3.el6 @anaconda-CentOS-201207051201 J386/6.3
…省略部分输出…
Available Packages
#还可以安装的软件包
389-ds-base.i686 1.2.10.2-15.el6 c6-media
389-ds-base-devel.i686 1.2.10.2-15.el6 c6-media
#软件名 版本 所在位置(光盘)
…省略部分输出…
  • yum list包名: 查询执行软件包的安装情况
[root@localhost yum.repos.d]# yum list samba
Available Packages samba.i686 3.5.10-125.el6 c6-media
#查询 samba 软件包的安装情况
  • yum search 关键字: 从 yum 源服务器上查找与关键字相关的所有软件包。
[root@localhost yum.repos.d]# yum search samba
#搜索服务器上所有和samba相关的软件包
========================N/S Matched:
samba =============================
samba-client.i686:Samba client programs
samba-common.i686:Files used by both Samba servers and clients
samba-doc.i686: Documentation for the Samba suite
…省略部分输出…
Name and summary matches only, use"search all" for everything.
  • yum info 包名:查询执行软件包的详细信息
[root@localhost yum.repos.d]# yum info samba
#查询samba软件包的信息
Available Packages <-没有安装
Name : samba <-包名
Arch : i686 <-适合的硬件平台
Version : 3.5.10 <―版本
Release : 125.el6 <—发布版本
Size : 4.9M <—大小
Repo : c6-media <-在光盘上
…省略部分输出…

yum安装命令

基本命令格式为:yum -y install 包名

  • install: 表示安装软件包

  • -y: 自动回答 yes。如果不加 -y,那么每个安装的软件都需要手工回答 yes

例如使用yum命令安装gcc:

[root@localhost yum jepos.d]#yum -y install gcc
#使用yum自动安装gcc

yum升级命令

使用 yum 升级软件包,需确保 yum 源服务器中软件包的版本比本机安装的软件包版本高。

yum 升级软件包常用命令如下:

  • yum -y update:升级所有软件包

  • yum -y update 包名:升级特定的软件包

yum卸载命令

使用 yum卸载软件包时,会同时卸载所有与该包有依赖关系的其他软件包,即便有依赖包属于系统运行必备文件,也会被 yum 无情卸载,带来的直接后果就是使系统崩溃

除非你能确定卸载此包以及它的所有依赖包不会对系统产生影响,否则不要使用 yum 卸载软件包。

yum卸载命令的基本格式:

[root@localhost yum.repos.d]# yum remove 包名
#卸载指定的软件包

yum管理软件组方法

yum 命令除了可以对软件包进行查询、安装、升级和卸载外还可完成对软件包组的查询、安装和卸载操作

yum查询软件组包含的软件

既然是软件包组,说明包含不只一个软件包,通过 yum 命令可以查询某软件包组中具体包含的软件包,命令格式如下:

[root@localhost ~]#yum groupinfo 软件组名
#查询软件组中包含的软件

yum安装软件组

使用 yum安装软件包组的命令格式如下:

[root@localhost ~]#yum groupinstall 软件组名
#安装指定软件组,组名可以由**grouplist**查询出来

yum命令卸载软件组

yum groupremove 软件组名

Linux源码包安装和卸载过程

由于 Linux 操作系统开放源代码,因此在其上安装的软件大部分也都是开源软件,例如 ApacheTomcatPHP 等。开源软件基本都提供源码下载,可采用源码安装的方式安装软件

注意,本节使用的源码包,指的是软件所有源代码的压缩包,其后缀名为 ".tar.gz"".tar.bz2";而 SRPM 源码包本质上属于 RPM 包,也就是源码的RPM包,其文件后缀为 ".src.rpm"。虽然都叫源码包,但不是一码事.

软件的源代码,也就是软件的原始数据,任何人都可以通过源代码查看该软件的设计架构和实现方法,但软件源代码无法再计算机中直接运行安装,需要将源代码通过编译转换为计算机可以识别的机器语言,然后才可以安装

Linux 系统中,绝大多数软件的源代码都是用 C 语言编写的,少部分用 C++(或其他语言)编写。因此要想安装源码包,必须安装 gcc 编译器(如果涉及 C++ 源码程序,还需要安装 gcc-c++

除了安装编译器,还需要安装 make 编译命令。要知道,编译源码包可不像编译一个 hello.c 文件那样轻松,包中含大量的源码文件,且文件之间有着非常复杂的关联,直接决定着各文件编译的先后顺序,因此手动编译费时费力,而使用 make 命令可以完成对源码包的自动编译。

在安装 make 命令之前,可使用如下命令查看其是否已经安装:

# rpm -q make
make-3.81-20.el6.i686

如果未安装,可使用 yum -y install make 命令直接安装 make

Linux源码包安装软件

以安装apache为例:

  1. 下载apache源码包,得到的源码包格式为压缩包.tar.gz.tar.bz2

将各种文件分门别类保存在对应的目录中,应该成为合格 Linux 管理员约定俗成的习惯。Linux 系统中用于保存源代码的位置主要有 2个,分别是 "/usr/src""/usr/local/src",其中 "/usr/src" 用来保存内核源代码,**"/usr/local/src"** 用来保存用户下载的源代码。

  1. 将源码包进行解压缩

tar -zxvf httpd-2.2.9.tar.gz|more

  1. 进入解压目录,执行如下命令:
[root@localhost ~]# ls
anaconda-ks.cfg httpd-2.2.9 httpd-2.2.9.tar.gz install.log install.log.syslog
[root@localhost ~]# cd httpd-2.2.9
  1. ./configure 软件配置与检查。
  • 检测系统环境是否符合安装要求。

  • 定义需要的功能选项。通过 "./configure--prefix=安装路径" 可以指定安装路径。注意,configure 不是系统命令,而是源码包软件自带的一个脚本程序,所以必须采用 "./configure" 方式执行("./" 代表在当前目录下)。

  • 系统环境的检测结果和定义好的功能选项写入 Makefile 文件,因为后续的编译和安装需要依赖这个文件的内容

[root@localhost httpd-2.2.9]# ./configure --prefix=/usr/local/apache2
checking for chosen layout...Apache
checking for working mkdir -p…yes
checking build system type...i686-pc-linux-gnu
checking host system type...i686-pc-linux-gnu
checking target system typa...i686-pc-linux-gnu
…省略部分输出…

--prefix 选项的含义为指定安装目录。

  1. make 编译。make 会调用 gcc 编译器,并读取 Makefile 文件中的信息进行系统软件编译。编译的目的就是把源码程序转变为能被 Linux 识别的可执行文件,这些可执行文件保存在当前目录下

make

  1. 正式开始安装软件.

make install

注意,如果在 "./configure""make" 编译中报错,则在重新执行命令前一定要执行 make clean 命令,它会清空 Makefile 文件或编译产生的 ".o" 头文件.

Linux源码包卸载

通过源码包方式安装的各个软件,其安装文件独自保存在 /usr/local/ 目录下的各子目录中。例如,apache 所有的安装文件都保存在 /usr/local/apache2 目录下。这就为源码包的卸载提供了便利。

源码包的卸载,只需要找到软件的安装位置,直接删除所在目录即可,不会遗留任何垃圾文件。需要读者注意的是,在删除软件之前,应先将软件停止服务

以删除 apache 为例,只需关闭 apache 服务后执行如下命令即可:

[root@localhost ~]# rm -rf /usr/local/apache2/

Linux源码包快速升级方法

Linux 系统中更新用源码包安装的软件,除了卸载重装这种简单粗暴的方法外,还可以下载补丁文件更新源码包,用新的源码包重新编译安装软件

使用补丁文件更新源码包,省去了用 ./configure 生成新的 Makefile 文件,还省去了大量的编译工作,因此效率更高

Linux补丁文件的生成和使用

Linux 系统中可以使用 diff 命令对比出新旧软件的不同,并生成补丁文件

diff命令基本格式:

[root@localhost ~]# diff 选项 old new
#比较old和new文件的不同

此命令中可使用如下几个选项:

  • a:将任何文档当作文本文档处理

  • b: 忽略空格造成的不同

  • B: 忽略空白行造成的不同

  • I: 忽略大小写造成的不同

  • N:当比较两个目录时,如果某个文件只在一个目录中,则在另一个目录中视作空文件

  • r: 当比较目录时,递归比较子目录;

  • -u: 使用同一输出格式

利用补丁文件更新旧文件,具体步骤如下:

  1. 创建两个文件,执行如下命令:
[root@localhost ~]# mkdir test
#建立测试目录
[root@localhost ~]# cd test
#进入测试目录
[root@localhost test]# vi old.txt
our
school
is
lampbrother
#文件old.txt,为了便于比较,将每行分开
[root@localhost test]# vi new.txt
our
school
is
lampbrother
in
Beijing
#文件new.txt
  1. 利用 diff 命令,比较两个文件(old.txtnew.txt)的不同,并生成补丁文件(txt.patch),执行代码如下:
[root@localhost test]# diff -Naur /root/test/old.txt /root/test/new.txt > txt. patch
#比较两个文件的不同,同时生成txt.patch补丁文件
[root@localhost test]#vi txt.patch
#查看一下这个文件
--/root/test/old.txt 2012-11-23 05:51:14.347954373 +0800
#前一个文件
+ + + /root/test/new.txt 2012-11-23 05:50:05.772988210 +0800
#后一个文件
@@-2, 3+2, 5@@
school
is
lampbrother
+in
+beijing
#后一个文件比前一个文件多两行(用+表示
  1. 利用补丁文件 txt.patch 更新 old.txt 旧文件,实现此步操作需利用 patch 命令,该命令基本格式如下:
[root@localhost test]# patch -pn < 补丁文件
#按照补丁文件进行更新

-pn 选项中,n为数字(例如 p1p2p3 等),pn 表示按照补丁文件中的路径,指定更新文件的位置

补丁文件是要打入旧文件的,但是当前所在目录和补丁文件中记录的目录不一定是匹配的,需要 "-pn" 选项来同步两个目录。

例如,当前位于 "/root/test/" 目录下(要打补丁的旧文件就在当前目录下),补丁文件中记录的文件目录为 "/root/test/dd.txt",如果写入 "-p1"(在补丁文件目录中取消一级目录),那么补丁文件会打入 "root/test/root/test/old.txt" 文件中,这显然是不对的;如果写入的是 "-p2"(在补丁文件目录中取消二级目录),补丁文件会打入 "/root/test/test/old.txt" 文件中,这显然也不对。如果写入的是 "-p3"(在补丁文件目录中取消三级目录),补丁文件会打入 "/root/test/old.txt" 文件中,old.txt 文件就在这个目录下,所以应该用 "-p3" 选项。

如果当前所在目录是 "/root/" 目录呢?因为补丁文件中记录的文件目录为 "/root/test/old.txt",所以这里就应该用 "-p2" 选项(代表取消两级目录),补丁打在当前目录下的 "test/old.txt" 文件上。

-pn 选项可以这样理解,即想要在补丁文件中所记录的目录中取消几个 "/"n 就是几。去掉目录的目的是和当前所在目录匹配

[root@localhost test]# patch -p3 < txt.patch
patching file old.txt
#给old.txt文件打补丁
[root@localhost test]# cat old.txt
#查看一下dd.txt文件的内容
our
school
is
lampbrother
in
Beijing
#多出了in Beijing两行

可以看到,通过使用补丁文件 txt.patch 对旧文件进行更新,使得旧文件和新文件完全相同。

  • 旧文件打补丁依赖的不是新文件,而是补丁文件,所以即使新文件被删除也没有关系

  • 补丁文件中记录的目录和当前所在目录需要通过 "-pn" 选项实现同步,否则更新可能失败。

apache打入补丁

本节仍以 apache 为例,通过从官网上下载的补丁文件 "mod_proxy_ftp_CVE-2008-2939.diff",更新 httpd-2.2.9 版本的 apache.

  1. apache 官网上下载补丁文件;

  2. 复制补丁文件到 apache 源码包解压目录中,执行命令如下:

[root@localhost ~]# cp mod_proxy_ftp_CVE-2008-2939.diff httpd-2.2.9

  1. 给旧 apache 打入补丁
[root@localhost ~]# cd httpd-2.2.9
#进入apache源码目录
[root@localhost httpd-2.2.9]# vi mod_proxy_ftp_CVE-2008-2939.diff
#查看补丁文件
--modules/proxy/mod_proxy_ftp.c (Revision 682869)
+ + + modules/proxy/mod_proxy_ftp.c (Revision 682870)
…省略部分输出…
#查看一下补丁文件中记录的目录,以便一会儿和当前所在目录同步
[root@localhost httpd-2.2.9]# patch - p0 < mod_proxy_ftp_CVE-2008-2939.diff
#打入补丁

因为当前在 "/root/httpd-2.2.9" 目录中,但补丁文件中记录的目录是 "modules/proxy/mod_proxy_ftp.c",就在当前所在目录中,因此一个 "/" 都不需要去掉,所以是 "-p0"

  1. 重新编译 apache 源码包,执行如下命令:

make

  1. 安装apache,执行如下命令:

make install

打补丁更新软件的过程比安装软件少了 "./configure" 步骤,且编译时也只是编译变化的位置,编译速度更快。

注意,如果未安装过 httpd-2.2.9,就需要先打入补丁,再依次执行 "./configure"、"make"、 "make install" 命令。

还原补丁

patch 命令不仅可以给旧文件打入补丁,还可以执行反操作,即恢复用补丁文件修改过的源文件,例如

patch -R <modjDroxy_ftp_CVE-2008-2939.diff

RPM包和源码包的选择

使用 RPM 包安装和使用源码包安装软件各有优缺点,不过,如果有 RPM 包的话,还是建议优先选择 RPM 包安装软件,毕竟后期管理起来更方便。当然,如果软件的架构差异太大,或者无法解决软件依赖性的问题,与其花大把的时间和精力解决软件之间的依赖,不如直接使用源码包的方式安装软件。

Linux函数库(静态函数库和动态函数库)及其安装过程

Linux 系统中存在大量的函数库。简单来讲,函数库就是一些函数的集合,每个函数都具有独立的功能且能被外界调用

函数库中的函数并不是以源代码的形式存在的,而是经过编译后生成的二进制文件,这些文件无法独立运行,只有链接到我们编写的程序中才可以运行

Linux系统中的函数库分为2种,分别是静态函数库(简称静态库)和动态函数库(也称为共享函数库,简称动态库或共享库),两者的主要区别在于,程序调用函数时,将函数整合到程序中的时机不同:

  • 静态函数库在程序编译时就会整合到程序中,换句话说,程序运行前函数库就已经被加载。这样做的好处是程序运行时不再需要调用外部函数库,可直接执行;缺点也很明显,所有内容都整合到程序中,编译文件会比较大,且一旦静态函数库改变,程序就需要重新编译。

  • 动态函数库在程序运行时才被加载程序中只保存对函数库的指向(程序编译仅对其做简单的引用)

使用动态函数库的好处是,程序生成的可执行程序体积比较小,且升级函数库时无需对整个程序重新编译;缺点是,如果程序执行时函数库出现问题,则程序将不能正确运行

目前,Linux 系统中大多数都是动态函数库(主要考虑到软件的升级方便),其中被系统程序调用的函数库主要存放在 "/usr/lib""/lib" 中;Linux 内核所调用的函数库主要存放在 "/lib/modules" 中。

Linux函数库的安装

Linux 发行版众多,不同 Linux 版本安装函数库的方式不同。CentOS 中,安装函数库可直接使用 yum 命令。

例如,安装 curses 函数库命令如下:

[root@Linux ~]# yum install ncurses-devel

正常情况下,函数库安装完成后就可以直接被系统识别,但凡事都有万一。

查看可执行程序调用了哪些函数库:

ldd -v 可执行文件名

-v 选项的含义是显示详细版本信息(不是必须使用)

例如,查看 ls 命令调用了哪些函数库,命令如下:

[root@localhost ~]# ldd /bin/ls
linux-gate.so.1 => (0x00d56000)
libselinux.so.1 =>/lib/libselinux.so.1 (0x00cc8000)
librt.so.1 =>/lib/librt.so.1 (0x00cb8000)
libcap.so.2 => /lib/libcap.so.2 (0x00160000)
libacl.so.1 => /lib/libacl.so.1 (0x00140000)
libc.so.6 => /lib/libc.so.6 (0x00ab8000)
libdl.so.2 => /lib/libdl.so.2 (0x00ab0000)
/lib/ld-linux.so.2 (0x00a88000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00c50000)
libattr.so.1 =>/lib/libattr.so.1 (0x00158000)

如果函数库安装后仍无法使用(运行程序时会提示找不到某个函数库),这时就需要对函数库的配置文件进行手动调整,也很简单,只需进行如下操作:

  1. 将函数库文件放入指定位置(通常放在 "/usr/lib""/lib" 中),然后把函数库所在目录写入 "/etc/ld.so.conf" 文件。例如:
[root@localhost ~]# cp *.so /usr/lib/
#把函数库复制到/usr/lib/目录中
[root@localhost ~]# vi /etc/ld.so.conf
#修改函数库配置文件
include ld.so.conf.d/*.conf
/usr/lib
#写入函数库所在目录(其实/usr/lib/目录默认已经被识别)

这里写入的是函数库所在的目录,而不单单是函数库的文件名。另外,如果自己在其他目录中创建了函数库文件,这里也可以直接在 "/etc/ld.so.conf" 文件中写入函数库文件所在的完整目录。

  1. 使用 ldconfig 命令重新读取 /etc/ld.so.conf 文件,把新函数库读入缓存.
[root@localhost ~]# ldconfig
#从/etc/ld.so.conf文件中把函数库读入缓存
[root@localhost ~]# ldconfig -p
#列出系统缓存中所有识别的函数库

分类:

后端

标签:

运维部署

作者介绍

E
EdwardWong
V1