RPMコマンドメモ

細かい部分はいつも忘れてしまうのでメモとして

# ファイル検索

```
# rpm -ql
```

`-q, --query` + `-l, --list`でパッケージのファイルを表示する。

```
# rpm -ql bash
/etc/skel/.bash_logout
/etc/skel/.bash_profile
...
```

未インストールのパッケージ情報を問い合わせる場合は `-p, --package`オプションを使用する。

```
# rpm -qpl httpd-2.4.6-88.el7.centos.x86_64.rpm 
/etc/httpd
/etc/httpd/conf
...
```
## 設定ファイルだけ表示する

`-c, --configfiles`オプションを使用する。

```
# rpm -qlc bash
/etc/skel/.bash_logout
/etc/skel/.bash_profile
...
```

## ドキュメントファイルだけ表示する

`d, --docfiles`オプションを使用する。

```
# rpm -qld bash
/usr/share/doc/bash-4.2.46/COPYING
/usr/share/info/bash.info.gz
...
```

## --dumpでファイルの詳しい情報を出力する

`--dump`オプションで詳しいファイル情報を出力できる。
出力される情報には`path` `size` `mtime` `digest` `mode` `owner` `group` `isconfig` `isdoc` `rdev` `symlink`が含まれている。

```
# rpm -q --dump bash
/etc/skel/.bash_logout 18 1523407981 2584c4ba8b0d2a52d94023f420b7e356a1b1a3f2291ad5eba06683d58c48570d 0100644 root root 1 0 0 X
/etc/skel/.bash_profile 193 1523407981 b0a7c216e09938367fcd2f072285f62d53eefb2a48baf8835415b965e029ca20 0100644 root root 1 0 0 X
/etc/skel/.bashrc 231 1523407981 898ed3bdcb749c665866ee2750ab50d7ac5da6b666546fcd952cfc4cbc0c33b4 0100644 root root 1 0 0 X
...
```


## 表示フォーマットを指定して出力

`--qf, --queryformat`でフォーマットを指定してファイル情報を出力する。
`--qf`を使うとパッケージに含まれる情報(名前、バージョンや含まれるファイル等)を任意のフォーマットで出力できる。

ファイル情報を出力する場合はフォーマット文字列を角括弧"[]"で囲う。
フォーマットの指定はCの`printf`に似た形式で行える。出力する情報の指定には`FILENAMES`, `FILESIZES`, `FILEMODES`のようなタグを使用する。タグは`%{TAGNAME}`形式で記述する。

使用できるすべてのタグは`--querytags`オプションで確認出来る。

```
# rpm --querytags
ARCH
ARCHIVESIZE
...
```

ファイル情報の出力には`OLDFILENAMES`, `FILESIZES`, `FILEMODES`, `FILERDEVS`, `FILEMTIMES`, `FILEMD5S`, `FILELINKTOS`, `FILEFLAGS`, `FILEUSERNAME`, `FILEGROUPNAME`, `FILEDEVICES`, `FILEINODES`, `FILELANGS`, `DIRINDEXES`, `BASENAMES`, `DIRNAMES`が使用できる。

次のサンプルはファイル名と所有者、グループ、パーミッション、ファイルサイズを表示している。

```
# rpm -q --queryformat "[%-40{FILENAMES}%-8{FILEUSERNAME}%-8{FILEGROUPNAME}%10{FILEMODES:perms}%8{FILESIZES}\n]" bash
/etc/skel/.bash_logout                  root    root    -rw-r--r--      18
/etc/skel/.bash_profile                 root    root    -rw-r--r--     193
/etc/skel/.bashrc                       root    root    -rw-r--r--     231
...
```

タグにタイプタグ`:typetag`を付与することで出力形式を変更できる。例えば上の例のように`FILEMODES`に`:perms`を付与することでパーミッションを一般的な文字列で出力できる。
`:octal`を指定すれば値を8進で表示することが出来る。使用可能な全てのタイプタグはmanのQUERY OPTIONSに記述がある。

```
# rpm -q --queryformat "[%-40{FILENAMES}%-8{FILEUSERNAME}%-8{FILEGROUPNAME}%10{FILEMODES:octal}%8{FILESIZES}\n]" bash
/etc/skel/.bash_logout                  root    root        100644      18
/etc/skel/.bash_profile                 root    root        100644     193
/etc/skel/.bashrc                       root    root        100644     231
```

### ファイルフラグを使ったファイルタイプの判別

`--queryformat`の`FILEFLAGS`で得られる情報にはファイルの種別が含まれている。

```
# rpm -q --queryformat "[%-40{FILENAMES}%-8{FILEFLAGS}\n]" bash
/etc/skel/.bash_logout                  17      
/etc/skel/.bash_profile                 17      
/etc/skel/.bashrc                       17    
...
/usr/share/doc/bash-4.2.46/COPYING      2       
/usr/share/info/bash.info.gz            2       
...
```

この情報は2進で表現されていて各ビットの意味は下記の通り。
上の例にある17はCONFIGとNOREPLACEにフラグが立っていることを示す。

| Name | Value |
|:--|--:|
|RPMFILE_CONFIG|(1 << 0)|
|RPMFILE_DOC|(1 << 1)|
|RPMFILE_DONOTUSE|(1 << 2)|
|RPMFILE_MISSINGOK|(1 << 3)|
|RPMFILE_NOREPLACE|(1 << 4)|
|RPMFILE_SPECFILE|(1 << 5)|
|RPMFILE_GHOST|(1 << 6)|
|RPMFILE_LICENSE|(1 << 7)|
|RPMFILE_README|(1 << 8)|
|RPMFILE_EXCLUDE|(1 << 9)|

また`:fflags`を付与することでフラグを文字で出力することもできる。

```
# rpm -q --queryformat "[%-40{FILENAMES}%-8{FILEFLAGS:fflags}\n]" bash
/etc/skel/.bash_logout                  cn      
/etc/skel/.bash_profile                 cn      
/etc/skel/.bashrc                       cn      
...
/usr/share/doc/bash-4.2.46/COPYING      d       
/usr/share/info/bash.info.gz            d       
...
```

# 依存性の確認

## パッケージの依存性を表示する

`-q, --query` + `-R, --requires`でパッケージが必要とするファイルやライブラリ等の情報を表示する。

```
# rpm -qR httpd | sort | uniq
/bin/sh
/etc/mime.types
httpd-tools = 2.4.6-80.el7.centos.1
libapr-1.so.0()(64bit)
libaprutil-1.so.0()(64bit)
libcrypt.so.1()(64bit)
libc.so.6()(64bit)
libc.so.6(GLIBC_2.14)(64bit)
libc.so.6(GLIBC_2.2.5)(64bit)
libc.so.6(GLIBC_2.3.4)(64bit)
libc.so.6(GLIBC_2.3)(64bit)
libc.so.6(GLIBC_2.4)(64bit)
libdb-5.3.so()(64bit)
libdl.so.2()(64bit)
libexpat.so.1()(64bit)
liblua-5.1.so()(64bit)
libm.so.6()(64bit)
libpcre.so.1()(64bit)
libpthread.so.0()(64bit)
libpthread.so.0(GLIBC_2.2.5)(64bit)
libselinux.so.1()(64bit)
libsystemd-daemon.so.0()(64bit)
libsystemd-daemon.so.0(LIBSYSTEMD_DAEMON_31)(64bit)
libz.so.1()(64bit)
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileCaps) <= 4.6.1-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(PayloadIsXz) <= 5.2-1
rtld(GNU_HASH)
systemd-units
system-logos >= 7.92.1-1
/usr/sbin/groupadd
/usr/sbin/useradd
```

このリストには4種類の情報が含まれている(ように見える)。

1. `/etc/mime.types`のようなファイル
2. `httpd-tools = 2.4.6-80.el7.centos.1`のようなパッケージとバージョン情報
3. `libselinux.so.1()(64bit)`のようなライブラリ情報
4. `rpmlib(CompressedFileNames) <= 3.0.4-1`のようなRPMパッケージのライブラリ情報

rpmlibについてはRedHatのメーリングリストにこんな記述がある
https://www.redhat.com/archives/rpm-list/2002-February/msg00313.html
> ... This ia a "tracking dependency" used in packaging to associate a
> package that contains/uses a feature/incompatibility with
> a version of rpmlib that can handle the feature/incompatibility.

## 依存性を提供するパッケージを探す

`-q, --query` + `--whatprovides`で依存性を提供するパッケージを確認できる。

```
# rpm -q --whatprovides "libsystemd-daemon.so.0()(64bit)"
systemd-libs-219-57.el7.x86_64
# rpm -q --whatprovides "/etc/mime.types"
mailcap-2.1.41-2.el7.noarch
# rpm -q --whatprovides "httpd-tools"
httpd-tools-2.4.6-80.el7.centos.1.x86_64
```

パッケージの指定(`httpd-tools = 2.4.6-80.el7.centos.1`, `system-logos >= 7.92.1-1`のような依存性)はバージョン情報を外して問い合わせする必要がある。

`rpmlib`の情報は`-R, --requires`では調査できない。

```
# rpm -q --whatprovides "rpmlib(FileDigests) <= 4.6.0-1"
no package provides rpmlib(FileDigests) <= 4.6.0-1
```

## ファイルやライブラリを必要とするパッケージを確認する。

`-q, --query` + `--whatrequires`でファイルやライブラリを必要とするパッケージを確認することが出来る。

たとえば`mailcap`パッケージが提供する`/etc/mime.types`ファイルは`httpd`パッケージが依存している。

```
# rpm -ql mailcap | grep mime.types
/etc/mime.types
# rpm -qR httpd | grep mime.types
/etc/mime.types
```

`--whatrequires`オプションを使用することで、あるパッケージが提供するリソースに依存しているパッケージを確認することが出来る。

```
# rpm -q --whatrequires /etc/mime.types
httpd-2.4.6-80.el7.centos.1.x86_64
```

### NOTE: --providesが提供するパッケージのリソース情報

manの説明では`rpm -q --provides`はあたかもそのパッケージが提供するすべてのリソース(Capability)を出力するようにも思えるが、実際には異なる。

> --provides
>  List capabilities this package provides.

例えば`httpd`パッケージが依存する、`mailcap`パッケージの`/etc/mime.types`ファイルは`mailcal`の`--provides`には含まれていない。

```
# rpm -q --provides mailcap
config(mailcap) = 2.1.41-2.el7
mailcap = 2.1.41-2.el7
```

`/etc/mime.types`は`rpm -ql`のリストに含まれている。

とあるパッケージが提供するすべてのCapabilityは下記3つの情報を合わせたものになる(と思う)。
- パッケージ名
- `rpm -ql`で得られるファイル一覧
- `rpm --provides`で得られる情報

# リンク

https://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/
http://rpm.org/documentation.html
https://linuxjm.osdn.jp/html/rpm/man8/rpm.8.html
http://refspecs.linuxbase.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/pkgformat.html