Ubuntu Weekly Recipe

第676回 aptコマンドの最新機能あれこれ

この記事を読むのに必要な時間:およそ 8 分

第675回ではapt-keyコマンドが廃止される理由を説明しました。それ以外にもaptコマンドには常に様々な変更が加えられています。今回はそれらをいくつかピックアップして紹介しましょう。

Apt 1.0.xから2.3.xまでの流れ

本連載でaptコマンドそのものを紹介したのは,7年以上前の第327回aptコマンドを使ってみようまで遡ります。当時はApt 1.0がリリースされて間もないころで,数週間後に登場したUbuntu 14.04 LTSにもApt 1.0が取り込まれています。Apt 1.0ではこれまで別々のコマンドだった各種ツールがサブコマンドとして一元化して使えるaptコマンドが実装された記念すべきリリースでもありました。

その後7年を経て,2021年7月時点でのバージョンは2.3.6にまで到達しています。まもなくリリースされる予定のDebian 11ではApt 2.2.xが採用される見込みです。またUbuntuも20.04はApt 2.0.x,21.04でApt 2.2.xとなり,Apt 2.3.x以降は21.10で採用されるでしょう。

今回は2020年3月にリリースされた2.0を含む,最新の2.3.6までのバージョンアップで追加された機能・変更点などを紹介します。

apt-patterns機能の追加

Apt 2.0の目玉とも言うべき機能がapt-patternsでしょう。これはaptitudeに存在した,パッケージに対する強力なパターンマッチング機能を移植したものです。従来のaptコマンドもパッケージ名の検索時等に簡易的な正規表現は可能でした。apt-patternsでは,さらにパッケージのステータスなども組み合わせたより詳細なマッチングが可能になっています。

パターンは?用語~省略文字のいずれかで開始します。用語のほうは複数の文字からなる文字列で,さらに(文字列)などの記述が続きます。よってbash等で記述する場合はシングルクオートでくくるのが一般的です。省略文字のほうはよりシンプルに記述できますが,すべてをサポートしているわけではありません。さらに「文字列」には特定のパターンや正規表現が入ります。これは外側のパターンに依存します。

manページにあるものも含めて,いくつか実例を見ていきましょう。

sudo apt remove ?garbage

?garbageないし~gは,インストールされたものの依存していたパッケージ等が削除されたため,安全にアンインストール可能なパッケージを選択します。removeサブコマンドと一緒に単体で利用する場合は,sudo apt autoremoveとほぼ同じ動作です。

sudo apt purge ?config-files

?config-filesないし~cはパッケージそのものは削除されたものの設定ファイルが残っているパッケージdpkg -lrcと表示されるパッケージ)を選択します。purgeコマンドと一緒に使うことで,これらのパッケージを完全削除します。

apt list '~i !~M (~slibs|~sperl|~spython)'

?installedないし~iはインストール済みのパッケージを,?automaticないし~Mは依存関係などによって自動的にインストールされたパッケージを,?section(正規表現)ないし~s正規表現はSectionフィールドが指定した正規表現に一致するパッケージを選択します。さらに複数のパターンの連結はAND検索になり,?or(パターン)ないし|はOR検索になります。さらに?not(パターン)ないし!パターンは状態を反転させます。これらの組み合わせによって,上記は「手動でインストール」されている,Sectionが「libs」「perl」「python」かのパッケージをリストアップします。

apt list '~i ~Vubuntu'

?version(正規表現)ないし~V正規表現は正規表現にマッチするバージョンを選択します。上記ではインストール済みのUbuntuパッチがあたっている(バージョンにXubuntuYの文字列が入る)パッケージをリストアップします。

apt list '?and(~D~nlibyaml-0-2,~n^lib)'

?name(正規表現)ないし~n正規表現でパッケージ名が正規表現にマッチするパッケージを選択します。さらに?depends(パターン)ないし~Dパターンによって依存関係にパターンに一致するパッケージが存在するものを選択します。上記は若干ややこしいですが,まずは~D~nlibyaml-0-2によって「libyaml-0-2」がDependsフィールドに含まれるパッケージをリストアップしています。これはapt reverse libyaml-0-2と同じです。さらに~n^lib?and()で繋げることで,そのパッケージリストの中から「libで始まるパッケージ名」だけを抽出しています。

このようにapt-patternsを駆使するとかなり複雑なパッケージのマッチングが可能になるのです。

apt satisfyコマンドの追加

Apt 1.9.0からaptおよびapt-getにsatisfyサブコマンドが追加されました。これはパッケージのDependsフィールドにある文字列を解釈し,それに応じてインストールするコマンドです。たとえばリポジトリには存在しないdebian/controlファイルのフィールドを元にパッケージをインストールしたり,deb-srcを有効化していない状態でbuild-dep相当の機能を実現したい場合に便利なコマンドとなります。

もう少し具体的に説明しましょう。aptにはもともとbuild-depというサブコマンドが存在しました。Debianパッケージは,そのパッケージを実行する際に必要なパッケージリストを表示した「Dependsフィールド」とは別に,パッケージをビルドする際に必要な「Build-Dependsフィールド」が存在します。もし何か特定のパッケージを手元でビルドしたい場合は,まずBuild-Dependsフィールドのパッケージをインストールしておく必要があります※1⁠。

※1
パッケージのビルドのためだけに環境を汚したくない場合は,pbuilderなどの構築時専用のchroot環境を作るというのもひとつの手です。ただしパッケージによっては「ソースパッケージを作るために必要なパッケージ」もあったりして,⁠きれいな環境」を維持するのは一筋縄ではいきません。

パッケージをビルドする場合,大抵はソースパッケージリポジトリ/etc/apt/sources.listdeb-srcで始まる行)を有効化しています。よって開発者はsudo apt build-dep FOOとするだけで,FOOパッケージをビルドするために必要なパッケージ一式をインストールできました。

しかしながら環境によっては,わざわざソースパッケージリポジトリを有効化したくない場合や,ソースパッケージには書かれていない依存関係に基づいてパッケージをインストールしたいことがあります。そこで使えるのがsatisfyサブコマンドです。このコマンドはDependsやBuild-Dependsに書かれている文字列をそのまま渡すことで,その内容を適切に解釈し,apt install相当のコマンドに変換してくれます。

たとえばBIOSを書き換えるflashromの依存関係は次のようになっています。

$ apt list flashrom
(中略)
Depends: libc6 (>= 2.28), libftdi1-2 (>= 1.2), libpci3 (>= 1:3.5.1), libusb-1.0-0 (>= 2:1.0.22)
(後略)

さらにソースパッケージリポジトリを有効化しているのであれば,構築時の依存関係は次のとおりであると確認できます。

$ apt showsrc flashrom
(中略)
Build-Depends: debhelper (>= 11), pkg-config, libpci-dev, libusb-1.0-0-dev [!hurd-i386], libftdi1-dev [!hurd-i386], meson
(後略)

これらのパッケージはsatisfyコマンドによって次のようにインストール可能です。

Dependsフィールドの場合:
$ sudo apt satisfy 'libc6 (>= 2.28), libftdi1-2 (>= 1.2), libpci3 (>= 1:3.5.1), libusb-1.0-0 (>= 2:1.0.22)'

Build-Dependsフィールドの場合:
$ sudo apt satisfy 'debhelper (>= 11), pkg-config, libpci-dev, libusb-1.0-0-dev [!hurd-i386], libftdi1-dev [!hurd-i386], meson'

debian/controlをパースして必要なパッケージをインストールするようなスクリプトを書いている場合,とても役に立つでしょう。

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member株式会社 創夢所属。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。