EC2 で動かしている Linux サーバーに、あるパッケージを入れたり消したりする前に「このパッケージは何に依存しているのか」「このパッケージを消すと何が巻き込まれるのか」を確かめる方法をまとめます。rpm コマンドで手元のパッケージやファイルを調べる方法と、dnf repoquery でリポジトリ側まで含めて調べる方法の両方を扱います。前提の環境は Amazon Linux 2023(パッケージ管理は DNF)です。rpm のオプションは RHEL 系のディストリビューションでも同じように使えます。
依存関係を調べる2つの道具
依存関係を調べるコマンドは、調べる対象によって使い分けます。
| 調べたいこと | コマンド |
|---|---|
| インストール済みのパッケージが必要とするもの | rpm -qR <パッケージ名> |
| 手元の .rpm ファイルが必要とするもの | rpm -qpR <ファイル名>.rpm |
| インストール済みのパッケージのうち、あるパッケージを必要とするもの | rpm -q --whatrequires <名前> |
| リポジトリにあるパッケージの依存先と、それを提供するパッケージ | dnf repoquery --deplist <パッケージ名> |
| 依存関係をツリーでたどる | dnf repoquery --tree --requires <パッケージ名> |
| 消したときに一緒に消えるもの | dnf remove --assumeno <パッケージ名> |
rpm はローカルの RPM データベースとファイルだけを見ます。dnf repoquery は有効なリポジトリのメタデータも見るので、まだ入れていないパッケージも調べられます。
rpm で依存関係を確かめる
1. インストール済みのパッケージが何に依存しているかを見る
-q(問い合わせ)に -R(--requires)を付けると、そのパッケージが必要とする「機能(capability)」が一覧で出ます。
rpm -qR openssh-server
出てくるのはパッケージ名ではなく、libcrypto.so.3()(64bit) や /bin/sh のような機能名です。どのパッケージがその機能を提供しているかを知りたいときは、--whatprovides で引きます。
rpm -q --whatprovides 'libcrypto.so.3()(64bit)'
2. 手元の .rpm ファイルの依存先を見る
ダウンロードしただけでまだ入れていない .rpm ファイルは、-p(--package)を付けてファイルを指定します。
rpm -qpR ./example-1.0-1.amzn2023.x86_64.rpm
入れる前に足りないものを洗い出したいときは、--test を付けてインストールを試します。--test は実際には何も変更せず、処理の流れだけを確かめるオプションです。
sudo rpm -ivh --test ./example-1.0-1.amzn2023.x86_64.rpm
足りない依存先があると、次のような形のエラーで一覧が出ます。
error: Failed dependencies:
<機能名> is needed by <パッケージ名>
3. あるパッケージに依存しているパッケージを見る(逆引き)
消そうとしているパッケージを、他のどのインストール済みパッケージが必要としているかは --whatrequires で調べます。
rpm -q --whatrequires openssl-libs
--whatrequires は指定した名前そのものを要求しているパッケージを返します。ライブラリのように、パッケージ名ではなく libssl.so.3()(64bit) などの機能名で要求されることが多いものは、先に --provides でそのパッケージが提供する機能名を確かめ、機能名で引き直すと漏れが減ります。
rpm -q --provides openssl-libs
rpm -q --whatrequires 'libssl.so.3()(64bit)'
アンインストールの前に影響を見るなら、-e(--erase)に --test を付ける方法もあります。
sudo rpm -e --test openssl-libs
dnf repoquery で依存関係を確かめる
Amazon Linux 2023 の dnf には repoquery が標準で入っています。リポジトリのメタデータを使うので、インストールしていないパッケージも調べられます。
1. 直接の依存先と、それを提供するパッケージを見る
--deplist は、直接の依存先と、それぞれを提供するパッケージをまとめて出します。
dnf repoquery --deplist nginx
出力は依存先(dependency:)ごとに、それを提供するパッケージ(provider:)が並ぶ形になります。rpm -qR と違って、機能名からパッケージ名への変換までやってくれます。
依存先を機能名ではなくパッケージ名だけで見たいときは、--requires に --resolve を組み合わせます。
dnf repoquery --requires --resolve nginx
2. 依存関係をツリーでたどる
--tree を --requires と組み合わせると、依存先を再帰的にたどってツリーで表示します。
dnf repoquery --tree --requires nginx
依存が深いパッケージでは出力が長くなるので、less に渡すと読みやすくなります。
3. インストール済みのパッケージから逆引きする
あるパッケージを必要としているパッケージを、インストール済みのものに限って探すには --installed と --whatrequires を組み合わせます。
dnf repoquery --installed --whatrequires openssl-libs
直接の依存元だけでなく、依存元の依存元までたどりたいときは --recursive を足します。--recursive は --whatrequires と一緒に使うオプションです。
dnf repoquery --installed --whatrequires openssl-libs --recursive
4. 消したときに巻き込まれるパッケージを見る
dnf remove は、指定したパッケージに依存しているパッケージも一緒に消します。さらに clean_requirements_on_remove が有効(既定で有効)なので、不要になった依存先も消えます。実行する前に、--assumeno を付けて確認だけします。
sudo dnf remove --assumeno openssl-libs
--assumeno はすべての質問に「いいえ」と答えるオプションなので、削除されるパッケージの一覧が表示されたところで何も変更せずに終わります。
動作を確かめる
コマンドが期待どおりに動いているかは、依存関係がはっきりしているパッケージで試すと分かります。
rpm -qR bash
dnf repoquery --deplist bash
rpm -qR では libc.so.6()(64bit) のような機能名の一覧が、dnf repoquery --deplist では dependency: ごとに provider: glibc-... のようなパッケージ名が表示されれば正しく動いています。
うまくいかないとき
package xxx is not installed と出る
rpm -q 系のコマンドはインストール済みのパッケージしか見ません。まだ入れていないパッケージは、.rpm ファイルがあれば rpm -qpR、無ければ dnf repoquery --deplist で調べます。
--whatrequires で何も出ないのに、消そうとすると依存エラーになる
依存元がパッケージ名ではなく機能名(共有ライブラリ名やファイルパス)で要求していると、パッケージ名での --whatrequires には出てきません。rpm -q --provides <パッケージ名> で提供している機能名を確かめ、その機能名で --whatrequires を引き直してください。
dnf repoquery の結果に入っているはずのパッケージが出ない
dnf の設定で exclude に指定されたパッケージは、repoquery の結果から外れることがあります。--disableexcludes=all を付けて試してください。
dnf repoquery --disableexcludes=all --deplist <パッケージ名>
--nodeps で無理に消してよいか
rpm -e --nodeps は依存関係の確認を飛ばして削除します。依存元のパッケージが動かなくなるので、依存関係を確かめたうえで影響が無いと分かっている場合に限って使います。


コメント