第675回ではapt-keyコマンドが廃止される理由を説明しました。それ以外にもaptコマンドには常に様々な変更が加えられています。今回はそれらをいくつかピックアップして紹介しましょう。
Apt 1.0.xから2.3.xまでの流れ
本連載でaptコマンドそのものを紹介したのは、
その後7年を経て、
今回は2020年3月にリリースされた2.
apt-patterns機能の追加
Apt 2.
パターンは?用語
」~省略文字
」(文字列)
」
manページにあるものも含めて、
- 「
sudo apt remove ?garbage
」 「 ?garbage
」ないし 「 ~g
」は、 インストールされたものの依存していたパッケージ等が削除されたため、 安全にアンインストール可能なパッケージを選択します。removeサブコマンドと一緒に単体で利用する場合は、 「 sudo apt autoremove
」とほぼ同じ動作です。 - 「
sudo apt purge ?config-files
」 「 ?config-files
」ないし 「 ~c
」はパッケージそのものは削除されたものの設定ファイルが残っているパッケージ ( dpkg -l
でrc
と表示されるパッケージ)を選択します。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.
もう少し具体的に説明しましょう。aptにはもともとbuild-depというサブコマンドが存在しました。Debianパッケージは、
パッケージをビルドする場合、/etc/
のdeb-src
で始まる行)sudo apt build-dep FOO
」
しかしながら環境によっては、
たとえば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/
Apt CLIの操作結果をJSON RPCで受け取る
Apt 1.
これはaptコマンドを使って何らかの操作を行ったときに、
まずはHookを受け取るスクリプトを作成します。
$ cat >> json-hook.sh << EOF #!/bin/bash trap '' SIGPIPE while true; do read request <&\$APT_HOOK_SOCKET || exit 1 if echo "\$request" | grep -q ".hello"; then echo "HOOK: HELLO" fi if echo "\$request" | grep -q ".bye"; then echo "HOOK: BYE" exit 0; fi echo HOOK: request \$request read empty <&\$APT_HOOK_SOCKET || exit 1 echo HOOK: empty \$empty if echo "\$request" | grep -q ".hello"; then printf '{"jsonrpc": "2.0", "result": {"version": "'0.2'"}, "id": 0}\n\n' >&\$APT_HOOK_SOCKET 2>/dev/null || exit 1 fi done EOF $ chmod +x json-hook.sh $ sudo cp json-hook.sh /usr/local/bin/
スクリプトでは$APT_
」
このスクリプトを、
$ cat <<EOF | sudo tee /etc/apt/apt.conf.d/99-json-hooks AptCli::Hooks::Install:: "/usr/local/bin/json-hook.sh"; AptCli::Hooks::Upgrade:: "/usr/local/bin/json-hook.sh"; AptCli::Hooks::Search:: "/usr/local/bin/json-hook.sh"; EOF
これで準備は完了です。試しに適当なパッケージを検索してみましょう。
$ apt search docker.io HOOK: HELLO HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.search.pre","params":{"command":"search","search-terms":["docker.io"],"unknown-packages":[],"packages":[]}} HOOK: empty HOOK: BYE ソート中... 完了 全文検索... 完了 docker-doc/hirsute,hirsute 20.10.2-0ubuntu2 all Linux container runtime -- documentation docker.io/hirsute,now 20.10.2-0ubuntu2 amd64 [インストール済み] Linux container runtime python3-docker/hirsute,hirsute 4.1.0-1.2 all Python 3 wrapper to access docker.io's control socket ruby-docker-api/hirsute,hirsute 1.22.2-1.1 all Ruby gem to interact with docker.io remote API HOOK: HELLO HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.search.post","params":{"command":"search","search-terms":["docker.io"],"unknown-packages":[],"packages":[]}} HOOK: empty HOOK: BYE
org.
から.search.
が叩かれ、.hello
で今度は.search.
が叩かれていることがわかります。検索の場合はsearch-terms
に検索文字列が入るだけです。
試しに存在しないパッケージ名だと次のような感じになります。
$ apt search docker.iot (前略) HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.search.fail","params":{"command":"search","search-terms":["docker.iot"],"unknown-packages":[],"packages":[]}} HOOK: empty HOOK: BYE
違うのは最後が.search.
ではなく.search.
になっていることです。
より実用的なのはinstallやupgradeでしょう。試しに次のようにパッケージのアップグレードが可能な状態で実行してみました。
$ apt list --upgradable 一覧表示... 完了 networkd-dispatcher/hirsute-updates,hirsute-updates 2.1-2~ubuntu21.04.1 all [2.1-1 からアップグレード可] ubuntu-drivers-common/hirsute-updates 1:0.9.0~0.21.04.1 amd64 [1:0.8.9.1 からアップグレード可] $ sudo apt upgrade (前略) HOOK: HELLO HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.pre-prompt", "params":{"command":"upgrade","search-terms":[],"unknown-packages":[], "packages":[{"id":767,"name":"networkd-dispatcher","architecture":"amd64","mode":"install","automatic":true, "versions":{"candidate":{"id":69990,"version":"2.1-2~ubuntu21.04.1","architecture":"all","pin":500, "origins":[{"archive":"hirsute-updates","codename":"hirsute","version":"21.04", "origin":"Ubuntu","label":"Ubuntu","site":"jp.archive.ubuntu.com"}, {"archive":"hirsute-updates","codename":"hirsute","version":"21.04", "origin":"Ubuntu","label":"Ubuntu","site":"jp.archive.ubuntu.com"}]}, "install":{"id":69990,"version":"2.1-2~ubuntu21.04.1","architecture":"all","pin":500, "origins":[{"archive":"hirsute-updates","codename":"hirsute","version":"21.04", "origin":"Ubuntu","label":"Ubuntu","site":"jp.archive.ubuntu.com"}, {"archive":"hirsute-updates","codename":"hirsute","version":"21.04", "origin":"Ubuntu","label":"Ubuntu","site":"jp.archive.ubuntu.com"}]}, "current":{"id":4737,"version":"2.1-1","architecture":"all","pin":500, "origins":[{"archive":"hirsute","codename":"hirsute","version":"21.04", "origin":"Ubuntu","label":"Ubuntu","site":"jp.archive.ubuntu.com"}, {"archive":"hirsute","codename":"hirsute","version":"21.04", "origin":"Ubuntu","label":"Ubuntu","site":"jp.archive.ubuntu.com"}]}}}, (中略) 以下のパッケージはアップグレードされます: networkd-dispatcher ubuntu-drivers-common (中略) HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.package-list", "params":{"command":"upgrade","search-terms":[],"unknown-packages":[], (中略) アップグレード: 2 個、新規インストール: 0 個、削除: 0 個、保留: 0 個。 (中略) HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.statistics", "params":{"command":"upgrade","search-terms":[],"unknown-packages":[], (中略) 67.3 kB のアーカイブを取得する必要があります。 この操作後に追加で 0 B のディスク容量が消費されます。 続行しますか? [Y/n] 取得:1 http://jp.archive.ubuntu.com/ubuntu hirsute-updates/main amd64 ubuntu-drivers-common amd64 1:0.9.0~0.21.04.1 [52.7 kB] 取得:2 http://jp.archive.ubuntu.com/ubuntu hirsute-updates/main amd64 networkd-dispatcher all 2.1-2~ubuntu21.04.1 [14.6 kB] (中略) HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.post", "params":{"command":"upgrade","search-terms":[],"unknown-packages":[], (後略)
今回はかなり複雑な情報が記載されています。だいぶ省略しましたが、
- org.
debian. apt. hooks. install. pre-prompt - org.
debian. apt. hooks. install. package-list - org.
debian. apt. hooks. install. statistics - org.
debian. apt. hooks. install. post
packages
には変更対象のパッケージとその詳細な情報が含まれています。Hookスクリプト側で適宜パースして、
ただし現時点でインターフェースは安定していません。Apt 1.
上記のHookが不要になったら、
$ sudo rm /etc/apt/apt.conf.d/99-json-hooks
その他の細かい機能変更
他にもいくつか機能変更が行われているため、
Apt 1.
Apt 1.src:ソースパッケージ名
」
Apt 2.
最後にちょっとした小技を。aptコマンドの結果をパイプに渡したときなどに、
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
これは
ただしapt list --upgradable
」
$ apt list -oApt::Cmd::Disable-Script-Warning=1 --upgradable | cat 一覧表示...
Aptには他にもさまざまなオプションが存在します。man apt.
やman apt_
、apt-config dump
などで有用なオプションを探してみると良いでしょう。