Ubuntuを使ううえでパッケージ管理は欠かせません。普段はソフトウェアセンターやapt-getコマンドからパッケージをインストールし、アップデーターから通知が届いたらアップデートする、それだけで充分です。しかし「この更新によって何が変わるのか」「 このファイルはどのパッケージに属しているのか」といったことを調べたくなるときもあるでしょう。今回はパッケージ管理で使えるちょっとしたコマンドをいくつか紹介します。
パッケージの変更履歴を取得する
パッケージを更新するとき、更新を反映する前に何が変わるのかを知りたいことがあるでしょう。
すべてのパッケージにはパッケージに関する変更履歴ファイル(changelogファイル)が付属します。ファイルは「/usr/share/doc/パッケージ名/changelog.Debian.gz」という名前で保存されていますので、これをlessコマンドなどで閲覧すれば、これまでの変更内容がわかります。
ただしローカルには、インストール済みパッケージの、直近の変更履歴しか保存されません。これからインストールしようとしているパッケージやアップグレードされるパッケージの更新履歴を過去に渡ってすべて閲覧したい場合は、「 apt-get changelog」を使用します。
$ apt-get changelog update-manager
変更履歴の内容はアップデートマネージャーに表示されるものと同じです。ただしPPAや外部リポジトリのようなchangelogs.ubuntu.com に掲載されない変更履歴は取得できません。もしPPAの変更履歴を取得したい場合は、Canonicalのrsalvetiが作成したPythonスクリプト を使うと良いでしょう。
$ sudo apt-get install python-launchpadlib
$ python generate-ppa-changelog.py -t cosmos-door -p marisa -s trusty
Launchpad APIを使っているため、python-launchpadlibパッケージが必要です。「 -t」オプションにPPAのユーザー名、「 -p」にPPAの名前、「 -s」にUbuntuのコードネームを指定します。たとえば「add-apt-repository ppa:cosmos-door/marisa」という形でPPAを追加した場合は、「 cosmos-door」がユーザー名、「 marisa」がPPAの名前になります。
すべてのパッケージの変更履歴を眺めたいのであれば、UbuntuUpdates.org も便利です。
インストール済みパッケージのファイルリストを取得する
インストール済みのパッケージのファイルリストは、dpkgコマンドを使って取得します。「 -L」オプションの後ろにパッケージ名を指定することで、そのパッケージのファイルリストが表示されるのです。次のコマンドはupdate-managerパッケージのファイルリストを取得する例です。
$ dpkg -L update-manager
/.
/usr
/usr/bin
/usr/bin/update-manager
/usr/lib
/usr/lib/python3
/usr/lib/python3/dist-packages
/usr/lib/python3/dist-packages/UpdateManager
/usr/lib/python3/dist-packages/UpdateManager/UpdateManager.py
(中略)
/usr/share/applications
/usr/share/applications/update-manager.desktop
/usr/share/doc/update-manager/changelog.gz
逆にファイル名から所属するパッケージを探したい場合は、「 -S」オプションを使用しましょう。
$ dpkg -S UpdateManager.py
update-manager: /usr/lib/python3/dist-packages/UpdateManager/UpdateManager.py
検索パターンにはシェルと同様のワイルドカード文字を使用できます。
$ dpkg -S UpdateManager.*
update-manager: /usr/share/update-manager/gtkbuilder/UpdateManager.ui
update-manager: /usr/lib/python3/dist-packages/UpdateManager/UpdateManager.py
「……により退避 (divert) された:……」というファイルが表示されることもあります。複数のパッケージでパス名がかぶっている場合に、インストール時に別名に退避したファイルがこのような表示になります。
未インストールのパッケージのファイルリストを取得する
「このファイルが欲しいのだけれど、どのパッケージをインストールすれば良いのかわからない」ということは往々にしてあります。そんな時はapt-fileコマンドを使いましょう[1] 。
$ sudo apt-get install apt-file
apt-fileはファイルリストを管理するデータベースを作成する必要があります。GUI環境であればインストール後に「apt-fileの更新が必要です」というダイアログが表示されます。「 実行する」をクリックすると、端末が起動し、自動的にデータベースの初期化を行ってくれますので、処理が完了するまで待ってください。端末が終了したらダイアログを閉じると良いでしょう。
CUIの場合や、リポジトリの更新によってファイルリストも更新する必要がある場合は、端末から次のコマンドを実行してください。
$ apt-file update
ファイルの検索はsearchコマンドで、ファイルリストの取得はlistコマンドで行います。
$ apt-file search UpdateManager.py
fs-uae-launcher: /usr/share/fs-uae-launcher/fs_uae_launcher/UpdateManager.py
update-manager: /usr/lib/python3/dist-packages/UpdateManager/UpdateManager.py
$ apt-file list fs-uae-launcher
fs-uae-launcher: /usr/bin/fs-uae-launcher
fs-uae-launcher: /usr/share/applications/fs-uae-launcher.desktop
fs-uae-launcher: /usr/share/doc/fs-uae-launcher/README.gz
(以下略)
Contentsファイルを生成していないPPAや外部リポジトリは検索対象外です。
Ubuntuをインストールしていない環境や別のリリースを調べたい場合は、「 Ubuntuパッケージ検索 」を使うと良いでしょう。
パッケージの中身を確認する
手元にバイナリパッケージがあるなら、インストールしなくてもdpkgコマンドを使って中身を確認できます。apt-fileでは追跡されないパッケージを確認するときに便利です。
apt-getでインストールできるパッケージであれば、バイナリパッケージ単独でダウンロードすることも簡単です。
$ apt-get download apport
取得:1 http://jp.archive.ubuntu.com/ubuntu/ trusty/main apport all 2.13.2-0ubuntu4 [177 kB]
177 kB を 0秒 で取得しました (510 kB/s)
$ ls
apport_2.13.2-0ubuntu4_all.deb
このパッケージがインストールするファイルリストは「--contents」オプションで取得します。
$ dpkg --contents apport_2.13.2-0ubuntu4_all.deb
drwxr-xr-x root/root 0 2014-02-15 07:56 ./
drwxr-xr-x root/root 0 2014-02-15 07:56 ./etc/
drwxr-xr-x root/root 0 2014-02-15 07:54 ./etc/apport/
-rw-r--r-- root/root 1172 2014-02-15 07:54 ./etc/apport/crashdb.conf
(以下略)
ちなみにUbuntuはLESSOPEN、LESSCLOSEに「lesspipe」が設定されています。UbuntuにインストールされるlesspipeはDebianパッケージも扱えるので、lessでも同じファイルリストを表示できます。
$ less apport_2.13.2-0ubuntu4_all.deb
異なるバージョン間のパッケージ差分を取得する
パッケージ間の差分はバイナリパッケージではなくソースパッケージをダウンロードしてきて、比較することになります。「 apt-get source」コマンドやbzrを使ってダウンロードし、「 debdiff」コマンドで差分を取ることになるのですが、若干面倒です。
もし1つ前のバージョンとの差分だけ確認したいのであれば、Launchpadで見るほうが簡単でしょう。
ソースパッケージ名を元に、Launchpadのパッケージステータスページにアクセスします。たとえばnginxなら次のようなアドレスになります。
最後の「nginx」を取得したいソースパッケージの名前に置き換えてください。バイナリパッケージ名がわかるなら「apt-get showsrc バイナリパッケージ名」でソースパッケージ名がわかるでしょう。
このページにはサポート中の各リリースのポケット(updatesやproposedなど)ごとの最新のバージョンが表示されています。バージョンの左にある三角ボタンから内容を展開すると、「 Available diffs」のところにバージョンごとの差分ファイルが用意されています。
図1 1つ前ないし2つ前との、unified形式の差分ファイルが用意されている
もっと古いバージョンも確認したければ、リリースごとのページにアクセスしましょう。たとえば12.04なら次のようなアドレスになります。
パッケージのインストール元リポジトリを調べる
PPAや外部リポジトリを追加した場合、あるパッケージがどのリポジトリ由来なのかわからなくなることがあります。そんなときは、「 apt-cache policy」を使いましょう。
$ apt-cache policy qt5-default
qt5-default:
インストールされているバージョン: 5.2.1+dfsg-0ubuntu1~trusty1~test2
候補: 5.2.1+dfsg-0ubuntu1~trusty1~test2
バージョンテーブル:
*** 5.2.1+dfsg-0ubuntu1~trusty1~test2 0
500 http://ppa.launchpad.net/canonical-qt5-edgers/qt5-beta2/ubuntu/ trusty/main amd64 Packages
100 /var/lib/dpkg/status
5.0.2+dfsg1-7ubuntu18 0
500 http://jp.archive.ubuntu.com/ubuntu/ trusty/main amd64 Packages
実際にインストールされているバージョン、そしてそのバージョンを提供するリポジトリのURLが出力されます。URLの左にある「500」や「100」といった数字は優先度(Pin-Priority)で、同じバージョンであれば値が大きいほうが優先的にインストールされます。
ちなみに、パッケージ名を指定せずに「apt-cache policy」を実行した場合は、現在有効になっているリポジトリのリストが得られます。
より新しいバージョンのパッケージを探す
Ubuntuは正式リリース後、いくつかの例外を除いて、ソフトウェア自体のバージョンが変わるような更新は提供しません。
たとえばUbuntu 13.10に「1.2」というバージョンのソフトウェアがあったとして、そのパッケージのバージョンが「1.2-1ubuntu1」だったとします。このとき1.2には致命的な不具合があり、1.3では修正されていたとしましょう。それでもUbutnu 13.10がリリースされたあとであれば、1.3のパッケージが13.10のリポジトリから提供されることは稀です。多くの場合は、正しく不具合報告が行われたのなら、1.3のうち必要な修正箇所のみを1.2に取り込んだうえで、「 1.2-1ubuntu1.1」としてリリースされることになります。
もしリリース版のUbuntuで、機能的により新しいバージョンのパッケージをインストールしたい場合は、おもに2つの方法が存在します。
Backportsリポジトリからインストールする
PPAを含む外部リポジトリを追加する
「Backportsリポジトリ 」は、リリース後の新しいバージョンを提供するためのリポジトリです。通常のリポジトリと異なり、比較的緩いルールで新しいバージョンのパッケージが取り込まれます。そのため、他のパッケージとの不整合を起こす可能性はあります。
Backportsリポジトリ自体はインストール直後から有効化されていますので、前項と同じ「apt-cache policy」でバージョンを確認できます。
$ apt-cache policy ansible
ansible:
インストールされているバージョン: (なし)
候補: 1.1+dfsg-1
バージョンテーブル:
1.4.4+dfsg-1~ubuntu13.10.1 0
100 http://jp.archive.ubuntu.com/ubuntu/ saucy-backports/universe amd64 Packages
1.1+dfsg-1 0
500 http://jp.archive.ubuntu.com/ubuntu/ saucy/universe amd64 Packages
これを見るとわかるとおり、優先度(Pin-Priority)が100と通常のリポジトリより低い値になっています。このため普通の方法では、ansibleは古いバージョン(1.1+dfsg-1)がインストールされてしまいます。Backportsリポジトリのパッケージを明示的にインストールしたい場合は、パッケージ名の後ろにリポジトリ名を追加しましょう。
$ sudo apt-get install ansible/saucy-backports
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
'ansible' にはバージョン '1.4.4+dfsg-1~ubuntu13.10.1' (Ubuntu:13.10/saucy-backports [all]) を選択しました
新しいバージョンをPPA経由で誰かが公開していることもしばしばあります。すでにUbuntuリポジトリに存在するパッケージの新しいバージョンであれば、Launchpadのパッケージステータスページから確認できます。
ページ下部にある「Other versions of 'ansible' in untrusted archives.」を展開してください。そこに同じパッケージの別バージョンを提供しているPPAが表示されます。ただしPPAで提供されるパッケージは何ら保証があるわけではありませんので、使用するかどうかよく考えたうえで判断してください。
図2 ページ下部のリンクを展開する
devscriptsパッケージに含まれる「rmadison」を使うと、UbuntuやDebianのリリースごとに採用されているバージョンのリストを取得できます
$ sudo apt-get install devscripts
$ rmadison -u debian,ubuntu ansible
debian:
ansible | 1.4.4+dfsg-1 | jessie | source, all
ansible | 1.4.4+dfsg-1 | sid | source, all
ubuntu:
ansible | 1.1+dfsg-1 | saucy/universe | source, all
ansible | 1.4.4+dfsg-1~ubuntu12.04.1 | precise-backports/universe | source, all
ansible | 1.4.4+dfsg-1~ubuntu12.10.1 | quantal-backports/universe | source, all
ansible | 1.4.4+dfsg-1~ubuntu13.10.1 | saucy-backports/universe | source, all
ansible | 1.4.4+dfsg-1 | trusty/universe | source, all
rmadisonがない環境であれば、CGIのページ (Debian版 )へ直接アクセスすれば同じ結果が得られます。
いろんな条件でパッケージを検索する
ソフトウェアセンターや「apt-cache search」はパッケージ名やパッケージの説明に対して検索した結果を返してくれますが、それ以外のメタデータでパッケージを検索したいこともあるでしょう。そんな時に便利なのがdctrl-toolsにある「grep-dctrl」コマンドです。
$ sudo apt-get install dctrl-tools
たとえばバージョン文字列に「ubuntu」が含まれるパッケージのパッケージ名とバージョンを表示するには、次のように実行します。
$ grep-aptavail -F Version ubuntu -s Package,Version
Package: acct
Version: 6.5.5-1ubuntu1
Package: acl
Version: 2.2.51-5ubuntu1
Package: acpid
Version: 1:2.0.10-1ubuntu3
(後略)
「-F」オプションに検索対象のフィールド、「 ubuntu」が検索パターン(正規表現も可能) 、「 -s」オプションに出力するフィールド一覧をカンマ区切りで指定しています。
コマンド名がgrep-aptavailの場合は、検索対象としてリポジトリのデータ(/var/lib/apt/lists以下のファイル)を使用します。grep-statusなら/var/lib/dpkg/status、grep-availableなら/var/lib/dpkg/availableが検索対象です。grep-dctrlを使えば、特定のファイルのみを検索対象にすることもできます。
正規表現や論理演算、出力制御、カウンティングもできますので、パッケージやリポジトリの状態をスクリプトで確認したい場合に非常に役立ってくれることでしょう。