RPM用法指南

Table of Contents

RPM起初是RedHat系统的包管理工具,目前已有多个系统支持RPM包(如SUSE)。

RPM由以下几个部分组成:

$ file /var/lib/rpm/*
/var/lib/rpm/Basenames:            Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Conflictname:         Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/__db.001:             Applesoft BASIC program data, first line number 18
/var/lib/rpm/__db.002:             a.out little-endian 32-bit pure executable
/var/lib/rpm/__db.003:             a.out little-endian 32-bit pure executable not stripped
/var/lib/rpm/Dirnames:             Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Enhancename:          Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Filetriggername:      Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Group:                Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Installtid:           Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Name:                 Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Obsoletename:         Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Packages:             Berkeley DB (Hash, version 9, native byte-order)
/var/lib/rpm/Providename:          Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Recommendname:        Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Requirename:          Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Sha1header:           Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Sigmd5:               Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Suggestname:          Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Supplementname:       Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Transfiletriggername: Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Triggername:          Berkeley DB (Btree, version 9, native byte-order)

1 查看帮助

rpm命令的参数选项太多,本人也尚未全部掌握,因此这里不会全部讲完,只讲重点。但是,即便是复杂也需要完整地把man rpm(8)看一遍,知道rpm命令能够做哪些工作,这样在使用时心里才有数。

man rpm(8)内容有很好的结构,在“SYNOPSIS”一节,就看得出rpm命令能干的事:

QUERYING AND VERIFYING PACKAGES
INSTALLING, UPGRADING, AND REMOVING PACKAGES
MISCELLANEOUS

这些便是重点了,在实际使用中,需要看好参数选项和参数说明即可。

2 查询包

非常常用的参数就是-q(–query),它负责对RPM Database进行查询,用法:

rpm {-q|--query} [select-options] [query-options]

不同的查询需求,对应不同的select-options和query-options,需要具体查看man。

2.1 列出系统中安装的包

命令:rpm -qa

也可以用通配符来匹配:

$ rpm -qa 'kernel*'
kernel-4.9.8-201.fc25.x86_64
kernel-devel-4.9.9-200.fc25.x86_64
kernel-devel-4.9.10-200.fc25.x86_64
kernel-debuginfo-common-x86_64-4.5.5-300.fc24.x86_64
kernel-modules-4.9.8-201.fc25.x86_64
kernel-4.9.9-200.fc25.x86_64
kernel-core-4.9.10-200.fc25.x86_64
kernel-4.9.10-200.fc25.x86_64
kernel-core-4.9.9-200.fc25.x86_64
kernel-debuginfo-common-x86_64-4.8.6-300.fc25.x86_64
kernel-modules-4.9.10-200.fc25.x86_64
kernel-modules-4.9.9-200.fc25.x86_64
kernel-headers-4.9.10-200.fc25.x86_64
kernel-core-4.9.8-201.fc25.x86_64

还可以结合管道做过滤:

$ rpm -qa | fgrep kernel
kernel-4.9.8-201.fc25.x86_64
kernel-devel-4.9.9-200.fc25.x86_64
kernel-devel-4.9.10-200.fc25.x86_64
kernel-debuginfo-common-x86_64-4.5.5-300.fc24.x86_64
kernel-modules-4.9.8-201.fc25.x86_64
kernel-4.9.9-200.fc25.x86_64
kernel-core-4.9.10-200.fc25.x86_64
texlive-l3kernel-svn41246-30.fc25.noarch
kernel-4.9.10-200.fc25.x86_64
kernel-core-4.9.9-200.fc25.x86_64
kernel-debuginfo-common-x86_64-4.8.6-300.fc25.x86_64
kernel-modules-4.9.10-200.fc25.x86_64
kernel-modules-4.9.9-200.fc25.x86_64
kernel-headers-4.9.10-200.fc25.x86_64
kernel-core-4.9.8-201.fc25.x86_64

上面两个示例列出了系统安装的内核相关包,想知道哪个内核包是最近安装的、哪个时辰安装的,可以带上–last参数:

$ rpm -qa 'kernel*' --last
kernel-devel-4.9.10-200.fc25.x86_64           2017年02月21日 星期二 22时05分12秒
kernel-headers-4.9.10-200.fc25.x86_64         2017年02月21日 星期二 22时04分54秒
kernel-4.9.10-200.fc25.x86_64                 2017年02月21日 星期二 22时04分42秒
kernel-modules-4.9.10-200.fc25.x86_64         2017年02月21日 星期二 22时04分25秒
kernel-core-4.9.10-200.fc25.x86_64            2017年02月21日 星期二 22时04分22秒
kernel-devel-4.9.9-200.fc25.x86_64            2017年02月17日 星期五 16时17分42秒
kernel-modules-4.9.9-200.fc25.x86_64          2017年02月17日 星期五 15时21分04秒
kernel-core-4.9.9-200.fc25.x86_64             2017年02月17日 星期五 15时20分00秒
kernel-4.9.9-200.fc25.x86_64                  2017年02月17日 星期五 15时15分46秒
kernel-4.9.8-201.fc25.x86_64                  2017年02月10日 星期五 13时54分42秒
kernel-modules-4.9.8-201.fc25.x86_64          2017年02月10日 星期五 13时54分32秒
kernel-core-4.9.8-201.fc25.x86_64             2017年02月10日 星期五 13时54分30秒
kernel-debuginfo-common-x86_64-4.8.6-300.fc25.x86_64 2016年11月23日 星期三 12时33分03秒
kernel-debuginfo-common-x86_64-4.5.5-300.fc24.x86_64 2016年06月26日 星期日 16时14分42秒

2.2 查询包信息

查询某个包是否安装,命令用法如下:

rpm -q [包名]

如果没有打印出内容,说明该包尚未安装到系统中。

例,在编译驱动时,先查看是否安装内核源码的头文件:

$ rpm -q kernel-headers
kernel-headers-4.9.10-200.fc25.x86_64

例,查看kernel-headers的具体信息:

$ rpm -q --info kernel-headers
Name        : kernel-headers
Version     : 4.9.10
Release     : 200.fc25
Architecture: x86_64
Install Date: 2017年02月21日 星期二 22时04分54秒
Group       : Development/System
Size        : 3951044
License     : GPLv2 and Redistributable, no modification permitted
Signature   : RSA/SHA256, 2017年02月16日 星期四 21时29分59秒, Key ID 4089d8f2fdb19c98
Source RPM  : kernel-4.9.10-200.fc25.src.rpm
Build Date  : 2017年02月16日 星期四 08时10分58秒
Build Host  : bkernel01.phx2.fedoraproject.org
Relocations : (not relocatable)
Packager    : Fedora Project
Vendor      : Fedora Project
URL         : http://www.kernel.org/
Summary     : Header files for the Linux kernel for use by glibc
Description :
Kernel-headers includes the C header files that specify the interface
between the Linux kernel and userspace libraries and programs.  The
header files define structures and constants that are needed for
building most standard programs and are also needed for rebuilding the
glibc package.

例,查看某个文件所属包:

rpm -qf `which ifconfig`
net-tools-2.0-0.40.20160329git.fc25.x86_6

例,列出包中包含哪些文件:

$ rpm -ql glibc
/etc/gai.conf
/etc/ld.so.cache
/etc/ld.so.conf
/etc/ld.so.conf.d
/etc/nsswitch.conf
/etc/rpc
/lib64/ld-2.24.so
/lib64/ld-linux-x86-64.so.2
/lib64/libBrokenLocale-2.24.so
...

例,列出包中的配置文件清单:

$ rpm -qc bash
/etc/skel/.bash_logout
/etc/skel/.bash_profile
/etc/skel/.bashrc

例,查询包安装和卸载时运行的脚本代码,这个非常有用,可以看到包安装之后额外做了哪些操作:

$ rpm -q --scripts bash
postinstall scriptlet (using <lua>):
nl        = '\n'
sh        = '/bin/sh'..nl
bash      = '/bin/bash'..nl
f = io.open('/etc/shells', 'a+')
if f then
  local shells = nl..f:read('*all')..nl
  if not shells:find(nl..sh) then f:write(sh) end
  if not shells:find(nl..bash) then f:write(bash) end
  f:close()
end
postuninstall scriptlet (using <lua>):
-- Run it only if we are uninstalling
if arg[2] == "0"
then
  t={}
  for line in io.lines("/etc/shells")
  do
    if line ~= "/bin/bash" and line ~= "/bin/sh"
    then
      table.insert(t,line)
    end
  end

  f = io.open("/etc/shells", "w+")
  for n,line in pairs(t)
  do
    f:write(line.."\n")
  end
  f:close()
end

例,查询包的依赖关系:

$ rpm -q --requires bash
/bin/sh
config(bash) = 4.3.43-4.fc25
filesystem >= 3
libc.so.6()(64bit)
libc.so.6(GLIBC_2.11)(64bit)
libc.so.6(GLIBC_2.14)(64bit)
libc.so.6(GLIBC_2.15)(64bit)
libc.so.6(GLIBC_2.2.5)(64bit)
libc.so.6(GLIBC_2.3)(64bit)
libc.so.6(GLIBC_2.3.4)(64bit)
libc.so.6(GLIBC_2.4)(64bit)
libc.so.6(GLIBC_2.8)(64bit)
libdl.so.2()(64bit)
libdl.so.2(GLIBC_2.2.5)(64bit)
libtinfo.so.6()(64bit)
rpmlib(BuiltinLuaScripts) <= 4.2.2-1
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(PayloadIsXz) <= 5.2-1
rtld(GNU_HASH)

3 安装、更新和卸载

3.1 安装包

用法如下:

rpm {-i|--install} [install-options] PACKAGE_FILE ...

例,安装一个包:

$ sudo rpm -ivh emacs-25.1-3.fc25.x86_64.rpm

参数v和参数h分别表示显示安装详情和进度。

例,忽略依赖关系安装:

$ sudo rpm -ivh --nodeps emacs-25.1-3.fc25.x86_64.rpm

3.2 升级包

用法如下:

rpm {-U|--upgrade} [install-options] PACKAGE_FILE ...

例,更新一个包(卸载旧版本、安装新版本):

$ sudo rpm -Uvh git-2.9.3-2.fc25.x86_64.rpm

3.3 卸载包

用法如下:

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

例,卸载一个软件包:

$ sudo rpm -e git

如果软件包有依赖关系是无法这样卸载的。带上–nodeps参数,将不会删除相关的依赖,而只删除包本身。比如我在Fedora上自己编译了内核,并打成RPM包,结果在卸载时要提示我卸载很多系统关键依赖,所以就得带上–nodeps参数。

4 验证包

RPM不仅提供增删改能力,还提供了验证机制,对已安装的包进行验证,知道每个文件变动情况。

例,bash包提供了多个配置文件,其中/etc/skel/.bashrc被我误删了,RPM的验证机制会发现这一变化:

$ rpm -V bash
遗漏   c /etc/skel/.bashrc

4.1 效验属性

如下,验证python-pip3包的输出结果:

$ rpm -V python3-pip | head -20
.......T.    /usr/bin/pip3
.......T.    /usr/bin/pip3.5
遗漏     /usr/lib/python3.5/site-packages/pip-8.1.2.dist-info
遗漏     /usr/lib/python3.5/site-packages/pip-8.1.2.dist-info/DESCRIPTION.rst
遗漏     /usr/lib/python3.5/site-packages/pip-8.1.2.dist-info/INSTALLER
遗漏     /usr/lib/python3.5/site-packages/pip-8.1.2.dist-info/METADATA
遗漏     /usr/lib/python3.5/site-packages/pip-8.1.2.dist-info/RECORD
遗漏     /usr/lib/python3.5/site-packages/pip-8.1.2.dist-info/WHEEL
遗漏     /usr/lib/python3.5/site-packages/pip-8.1.2.dist-info/entry_points.txt
遗漏     /usr/lib/python3.5/site-packages/pip-8.1.2.dist-info/metadata.json
遗漏     /usr/lib/python3.5/site-packages/pip-8.1.2.dist-info/top_level.txt
S.5....T.    /usr/lib/python3.5/site-packages/pip/__init__.py
.......T.    /usr/lib/python3.5/site-packages/pip/__main__.py
S.5....T.    /usr/lib/python3.5/site-packages/pip/__pycache__/__init__.cpython-35.pyc
S.5....T.    /usr/lib/python3.5/site-packages/pip/__pycache__/__main__.cpython-35.pyc
S.5....T.    /usr/lib/python3.5/site-packages/pip/__pycache__/basecommand.cpython-35.pyc
S.5....T.    /usr/lib/python3.5/site-packages/pip/__pycache__/baseparser.cpython-35.pyc
S.5....T.    /usr/lib/python3.5/site-packages/pip/__pycache__/cmdoptions.cpython-35.pyc
S.5....T.    /usr/lib/python3.5/site-packages/pip/__pycache__/download.cpython-35.pyc
S.5....T.    /usr/lib/python3.5/site-packages/pip/__pycache__/exceptions.cpython-35.pyc

可见第一列有大量类似“S.5….T.”的输出,这表示验证的属性。根据man rpm(8)描述,每位对应的属性如下:

S file Size differs
M Mode differs (includes permissions and file type)
5 digest (formerly MD5 sum) differs
D Device major/minor number mismatch
L readLink(2) path mismatch
U User ownership differs
G Group ownership differs
T mTime differs
P caPabilities differ

如果对应的属性没有问题,该位置以“.”表示。“S.5….T.”表示对应的文件大小(S)、文件MD5(5)和最后修改时间(T)不对。

一般看到大量这样的改变,可能的原因要么是手动安装过对应的软件,要么是通过其他途径升级过软件,或者是出了安全事故。上例的情况就是我用pip3命令做了自身升级。

例,对系统中所有包进行全面验证:

$ rpm -Va

5 RPM Database管理

5.1 重新构造rpm数据库

例,当我运行dnf命令时,提示:

  错误:rpmdb: BDB0113 Thread/process 29848/140606613985024 failed: BDB1507 Thread died in Berkeley DB library
  错误:db5 错误(-30973) 源自 dbenv->failchk: BDB0087 DB_RUNRECOVERY: Fatal error, run database recovery
  错误:cannot open Packages index using db5 -  (-30973)
  错误:无法从 /var/lib/rpm 打开软件包数据库
  错误:Error: rpmdb open failed

说明RPM的数据库损坏,这时需要重建数据。

1、先备份/var/lib/rpm,拷贝一份到其他目录,防止彻底丢失;

2、验证存软件包的库是否有问题:dbverify /var/lib/rpm/Packages;

3、重建:rpm –rebuilddb

4、dnf clean all,再dnf update

6 其他

6.1 deb包转rpm包

系统需要安装alien。然执行:

alien -r xxx.deb

-r参数表示转换成rpm包。

6.2 解压RPM包

RPM实际上使用的CPIO格式打包的,用rpm2cpio命令转成CPIO格式即可:

rpm2cpio chkconfig-1.4-1.fc22.src.rpm | cpio -div

或者转成gzip格式解压:

$ rpm2archive git-2.9.3-2.fc25.x86_64.rpm
$ file git-2.9.3-2.fc25.x86_64.rpm.tgz
git-2.9.3-2.fc25.x86_64.rpm.tgz: gzip compressed data, last modified: Wed Feb 22 14:16:00 2017, from Unix