第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: BYEorg.から.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などで有用なオプションを探してみると良いでしょう。