rpmコマンドで始めるパッケージ管理 - 初心者から上級者まで


## CentOSシステムでrpmコマンドを使用してパッケージを管理

**機能**：インストール、アンインストール、アップグレード、クエリ、検証、データベースメンテナンス

### 1. インストール
```shell
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` #インストール後にパッケージと同名のスクリプトを実行しない

#### よく使用される組み合わせ
```shell
rpm -ivh PACKAGE_FILE ...
```

#### 使用例
- 依存関係不要の場合
```shell
[root@localhost Packages]$ rpm -ivh vsftpd-3.0.3-35.el8.x86_64.rpm 
Verifying...                          ################################# [100%]
Preparing...                          ################################# [100%]
Updating / installing...
   1:vsftpd-3.0.3-35.el8              ################################# [100%]
```
- 依存関係が必要でエラーが発生する場合
```shell
[root@localhost Packages]$ rpm -ivh httpd-2.4.37-43.module_el8.5.0+1022+b541f3b1.x86_64.rpm
error: Failed dependencies:
       httpd-filesystem = 2.4.37-43.module_el8.5.0+1022+b541f3b1 is needed by 
       httpd-2.4.37-43.module_el8.5.0+1022+b541f3b1.x86_64
       httpd-tools = 2.4.37-43.module_el8.5.0+1022+b541f3b1 is needed by
       httpd-2.4.37-43.module_el8.5.0+1022+b541f3b1.x86_64
```

### 2. パッケージのアップグレードとダウングレード
```shell
rpm {-U|--upgrade} [install-options] PACKAGE_FILE...
rpm {-F|--freshen} [install-options] PACKAGE_FILE...
```

- `upgrade`: 旧バージョンのパッケージが存在する場合は「アップグレード」、存在しない場合は「インストール」
- `freshen`: 旧バージョンのパッケージが存在する場合は「アップグレード」、存在しない場合は何も行わない
- `--oldpackage` #ダウングレード
- `--force` #強制インストール

#### よく使用される組み合わせ
```shell
rpm -Uvh PACKAGE_FILE ...
rpm -Fvh PACKAGE_FILE ...
```

#### アップグレードの注意点
- カーネルのアップグレードを行わないこと。Linuxは複数のカーネルバージョンを共存させることができるため、新バージョンのカーネルを直接インストールする。
- 元のパッケージの設定ファイルがインストール後に変更されていた場合、アップグレード時に新バージョンの同じ設定ファイルは直接上書きせず、新バージョンのファイルを`FILENAME.rpmnew`にリネームして保存する

### 3. パッケージのクエリ
```shell
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をクエリ

#### よく使用されるクエリの組み合わせ
```shell
-qi PACKAGE
-qf FILE
-qc PACKAGE
-ql PACKAGE
-qd PACKAGE
-qpi PACKAGE_FILE
-qpl PACKAGE_FILE
-qa
```

#### 使用例
- 全てのインストール済みのパッケージをリストアップ
```shell
[root@rocky86 h]# rpm -qa
......
[root@rocky86 h]# rpm -qa | grep passwd
passwd-0.80-4.el8.x86_64
```

- パッケージがインストールされているかどうかを確認する
    - インストール済み
    ```shell
    [root@rocky86 h]# rpm -q nginx
    nginx-1.14.1-9.module+el8.4.0+542+81547229.x86_64
    [root@rocky86 h]# echo $?
    0
    ```

    - インストールされていない場合
    ```shell
    [root@rocky86 h]# rpm -q php
    package php is not installed
    [root@rocky86 h]# echo $?
    1
    ```

- パッケージの詳細情報をクエリ
    - インストール済み
    ```shell
    [root@rocky86 h]# rpm -qi nginx
    Name       : nginx
    Epoch      : 1
    Version    : 1.14.1
    Release    : 9.module+el8.4.0+542+81547229
    Architecture: x86_64
    Install Date: Thu 14 Jul 2022 10:11:12 AM CST
    Group      : System Environment/Daemons
    Size       : 1669719
    License    : BSD
    Signature  : RSA/SHA256, Thu 10 Jun 2021 05:22:38 PM CST, Key ID 
                 15af5dac6d745a60
    Source RPM : nginx-1.14.1-9.module+el8.4.0+542+81547229.src.rpm
    Build Date : Thu 10 Jun 2021 05:10:40 PM CST
    Build Host : ord1-prod-x86build005.svc.aws.rockylinux.org
    Relocations: (not relocatable)
    Packager   : infrastructure@rockylinux.org
    Vendor     : Rocky
    URL        : http://nginx.org/
    Summary    : A high performance web server and reverse proxy server
    Description: 
    Nginx is a web server and a reverse proxy server for HTTP, SMTP, POP3 and
    IMAP protocols, with a strong focus on high concurrency, performance and low
    memory usage.
    ```

    - インストールされていない場合、パッケージファイルを指定
    ```shell
    [root@rocky86 h]# rpm -qi httpd
    package httpd is not installed
    
    [root@rocky86 h]# rpm -qip httpd-2.4.37-47.module+el8.6.0+823+f143cee1.1.x86_64.rpm
    Name       : httpd
    Version    : 2.4.37
    Release    : 47.module+el8.6.0+823+f143cee1.1
    Architecture: x86_64
    Install Date: (not installed)
    Group      : System Environment/Daemons
    Size       : 4499434
    License    : ASL 2.0
    Signature  : RSA/SHA256, Wed 11 May 2022 02:40:26 AM CST, Key ID 
                 15af5dac6d745a60
    Source RPM : httpd-2.4.37-47.module+el8.6.0+823+f143cee1.1.src.rpm
    Build Date : Wed 11 May 2022 02:06:03 AM CST
    Build Host : ord1-prod-x86build003.svc.aws.rockylinux.org
    Relocations: (not relocatable)
    Packager   : infrastructure@rockylinux.org
    Vendor     : Rocky
    URL        : https://httpd.apache.org/
    Summary    : Apache HTTP Server
    Description: 
    The Apache HTTP Server is a powerful, efficient, and extensible
    web server.
    ```

- ファイルに基づいてパッケージ情報をクエリ
```shell
[root@rocky86 h]# rpm -qf /usr/sbin/nginx 
nginx-1.14.1-9.module+el8.4.0+542+81547229.x86_64
[root@rocky86 h]# rpm -qf /usr/bin/passwd
passwd-0.80-4.el8.x86_64
[root@rocky86 h]# rpm -qf /etc/passwd
setup-2.12.2-6.el8.noarch
```

- 未インストールパッケージについてファイルの情報をクエリ
```shell
[root@rocky86 h]# rpm -qpf httpd-2.4.37-47.module+el8.6.0+823+f143cee1.1.x86_64.rpm
httpd-2.4.37-47.module+el8.6.0+823+f143cee1.1.x86_64
```

- カスタマイズでコンパイルしたファイルがどのパッケージにも属していない場合
```shell
[root@rocky86 0727]# rpm -qf test 
file /root/0727/test is not owned by any package
```

- 設定ファイルをクエリ
    - インストール済み
    ```shell
    [root@rocky86 0727]# rpm -qc nginx
    /etc/logrotate.d/nginx
    /etc/nginx/fastcgi.conf
    ......
    ```

    - インストールされていない場合、パッケージファイルを指定
    ```shell
    [root@rocky86 h]# rpm -qpc httpd-2.4.37-47.module+el8.6.0+823+f143cee1.1.x86_64.rpm
    /etc/httpd/conf.d/autoindex.conf
    /etc/httpd/conf.d/userdir.conf
    ......
    ```

- パッケージ内の全ファイルをリスト
    - インストール済み
    ```shell
    [root@rocky86 0727]# rpm -ql nginx
    /etc/logrotate.d/nginx
    /etc/nginx/fastcgi.conf
    ......
    ```

    - インストールされていない場合、パッケージファイルを指定
    ```shell
    [root@rocky86 h]# rpm -qpl httpd-2.4.37-47.module+el8.6.0+823+f143cee1.1.x86_64.rpm
    /etc/httpd/conf
    /etc/httpd/conf.d/autoindex.conf
    /etc/httpd/conf.d/userdir.conf
    ......
    ```

- ドキュメントファイルをクエリ
    - インストール済み
    ```shell
    [root@rocky86 0727]# rpm -qd nginx
    /usr/share/doc/nginx/CHANGES
    /usr/share/doc/nginx/README
    /usr/share/man/man3/nginx.3pm.gz
    ......
    ```

    - インストールされていない場合、パッケージファイルを指定
    ```shell
    [root@rocky86 h]# rpm -qpd httpd-2.4.37-47.module+el8.6.0+823+f143cee1.1.x86_64.rpm | head
    /usr/share/doc/httpd/ABOUT_APACHE
    /usr/share/doc/httpd/CHANGES
    ......
    ```

- インストールスクリプトをクエリ
```shell
[root@rocky86 h]# rpm -q --scripts postfix
preinstall scriptlet (using /bin/sh):
# Add user and groups if necessary
/usr/sbin/groupadd -g 90 -r postdrop 2>/dev/null
/usr/sbin/groupadd -g 89 -r postfix 2>/dev/null
......
```

- ショートカットインストール
    - パッケージがインストールされていない場合のみ実行
    ```shell
    [root@rocky86 v]# rpm -q vsftpd || rpm -ivh vsftpd-3.0.3-35.el8.x86_64.rpm
    package vsftpd is not installed
    Verifying...                          ################################# [100%]
    Preparing...                          ################################# [100%]
    Updating / installing...
       1:vsftpd-3.0.3-35.el8              ################################# [100%]
    ```


### 4. パッケージのアンインストール
```shell
rpm {-e|--erase} [--allmatches] [--nodeps] [--noscripts] [--notriggers] [--test] PACKAGE_NAME ...
```

#### 使用例
- パッケージのアンインストール
```shell
[root@rocky86 v]# rpm -evh vsftpd
Preparing...                          ################################# [100%]
Cleaning up / removing...
   1:vsftpd-3.0.3-35.el8              ################################# [100%]
```

- パッケージのアンインストール確認
```shell
[root@rocky86 v]# rpm -q vsftpd
package vsftpd is not installed
```

- ショートカットアンインストール（パッケージがインストールされている場合のみ実行）
```shell
[root@rocky86 v]# rpm -q vsftpd && rpm -evh vsftpd
vsftpd-3.0.3-35.el8.x86_64
Preparing...                          ################################# [100%]
Cleaning up / removing...
   1:vsftpd-3.0.3-35.el8              ################################# [100%]
```

**注意**：パッケージをアンインストールしても、対応する設定ファイルは削除されず、`FILENAME.rpmsave`として保存されます。


### 5. パッケージ検証

パッケージをインストールする際に、システムはパッケージの出所が正当かどうかを確認します。
パッケージの完全性と署名をチェックします。

```shell
rpm -K|checksig rpmfile
```

#### 使用例

```shell
[root@rocky86 v]# rpm -K vsftpd-3.0.3-35.el8.x86_64.rpm 
vsftpd-3.0.3-35.el8.x86_64.rpm: digests signatures OK
```

#### 必要な公開鍵をインポートする

パッケージの出所と完全性を確認する前に、必要な公開鍵をインポートする必要があります。

##### 公開鍵をインポートする

```shell
[root@rocky86 v]# rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial
```

##### インポートされた公開鍵を確認する

```shell
[root@rocky86 v]# rpm -qa "gpg-pubkey"
gpg-pubkey-2f86d6a1-5cf7cefb
gpg-pubkey-6d745a60-60287f36
```

##### 公開鍵の詳細を確認する

```shell
[root@rocky86 v]# rpm -qi gpg-pubkey-6d745a60-60287f36
Name       : gpg-pubkey
Version    : 6d745a60
Release    : 60287f36
Architecture: (none)
......
```

ソフトウェアをインストールする際に、パッケージ内の各ファイルのメタデータ（サイズ、権限、所有者、タイムスタンプなど）を記録します。これにより、パッケージ内のファイルがインストール時から変更されていないかを確認できます。

```shell
rpm {-V|--verify} [select-options] [verify-options]
```

#### フィールドの説明

- `S` ファイルサイズが異なる
- `M` ファイルの権限またはファイルタイプが異なる
- `5` md5 チェックサムが異なる
- `D` デバイスのメジャー番号/マイナー番号が異なる
- `L` シンボリックリンクのパスが異なる
- `U` 所有者が変更された
- `G` グループが変更された
- `T` タイムスタンプが変更された
- `P` キャパシティが変更された
- `c|d|g|l|r` ファイルタイプ
  - `c` 設定ファイル
  - `d` データファイル
  - `g` 不明なファイル
  - `l` ライセンスファイル
  - `r` README ファイル

`.` インストール時から変更がない場合

#### 使用例

```shell
# インストール後にファイルが変更されていない場合
[root@rocky86 v]# rpm -V vsftpd
[root@rocky86 v]# echo $?
0

# インストール後に設定ファイルが変更された場合
[root@rocky86 v]# rpm -V nginx
S.5....T. c /etc/nginx/nginx.conf
[root@rocky86 v]# echo $?
1
```

### 6. データベース

rpmパッケージのインストール時に生成された情報は、すべてrpmデータベースに保存されます。

```shell
[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
......
```

データベースの再構築が可能です。

```shell
rpm {--initdb|--rebuilddb}
```

- `initdb` データベースが存在しない場合は新規作成、存在する場合は何もしない
- `rebuilddb` インストール済みパッケージのヘッダーを使用してデータベースインデックスディレクトリを再構築

### 7. パッケージの更新ログを表示する

```shell
rpm -q --changelog packageName
```

#### 使用例

```shell
[root@rocky86 v]# rpm -q --changelog nginx 
* Thu Jun 10 2021 Mustafa Gezen <mustafa@rockylinux.org> - 1.14.1-9
- Debrand default pages
* Fri Aug 30 2019 Lubos Uhliarik <luhliari@redhat.com> - 1:1.14.1-9
......
```