$ man シェル芸botのman

はじめに

普通の Linux 環境では、$ man コマンド のように実行することで、コマンドのマニュアルを見ることができますが、シェル芸botman コマンドを実行しても、(2019.7.17 時点では)マニュアルを見ることができません。

これは、Ubuntu の Docker イメージで設定されているものをうまく利用し、シェル芸bot の Docker イメージサイズの低減を図っているためで、ここではそのあたりの仕組みを解説してみます。

環境は ShellgeiBot-Image のベースに使っている ubuntu:19.04 (86f1f717b6d8) を想定しています。

Ubuntu Docker イメージの man

素の ubuntu:19.04 の Docker イメージからコンテナを起動します。

(Host)$ docker run -it --rm ubuntu:19.04

bash が起動するので、man ls を実行すると、ls コマンドのマニュアルの代わりに、次のような固定のメッセージが出力されます。

(Container)# man ls
This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, including manpages, you can run the 'unminimize'
command. You will still need to ensure the 'man-db' package is installed.

実際の man の中身を見てみると、単純なスクリプトファイルが置かれているだけです。

(Container)# cat $(which man)
#!/bin/sh
echo "This system has been minimized by removing packages and content that are"
echo "not required on a system that users do not log into."
echo ""
echo "To restore this content, including manpages, you can run the 'unminimize'"
echo "command. You will still need to ensure the 'man-db' package is installed."

Docker は、アプリケーションを動かすためだけの環境として使われることが多く、そのような用途ではコマンドのドキュメント類はほとんど不要なのでしょう。 できるだけ配布するイメージを軽量化するために、man のようなドキュメント類は削除されているようです。

man を復活させる

メッセージに書かれている通り、削除されたパッケージ類を復元する手段として、unminimize スクリプトが用意されています。 unminimize を実行すると、概ね以下のような処理が実行されます。

  1. /etc/dpkg/dpkg.cfg.d/excludes にある、パッケージ除外設定ファイルを削除して無効化
  2. apt-get update, apt-get upgrade を実行し、パッケージを更新
  3. /usr/share/man/, /usr/share/doc/, /usr/share/locale/ 以下にファイルを配置するパッケージ類を(シェルワンライナーごりごりで)検索し、対象のパッケージを再インストール
  4. /usr/bin/man.REAL に待避させてあった man のバイナリを /usr/bin/man に戻す

あとは、apt-getman-db パッケージをインストールすれば、man コマンドが利用可能になります。

シェル芸bot の Docker イメージでは

シェル芸の実行にあまり必要でないパッケージは、なるべく Docker イメージに含めないようにし、ビルド時間があまり長くならないようメンテナンスしてきました。 Docker イメージに含めるデータ容量が増えると、データの転送にかかる時間にも結構影響してしまうため、軽量化にも気を配るようにしています。

man については、あまりシェル芸で参照する意味がないのではと考え、unminimize を実行せず、ドキュメント類は基本的に含めないようにしています。 ただ、該当する man がない場合のエラーメッセージを利用したシェル芸ができるよう、/usr/bin/man.REAL/usr/bin/man に戻す処理だけ実行しています(参考)。 man-db パッケージは、おそらく何か他のパッケージの依存で入っていると思います。

コマンドの使い方を調べたい場合は、手元の PC で調べてもらうか、ウェブ上のマニュアルを参照してもらえばと思いますが、シェル芸bot でのデータソースとしてや、textimg 等を併用してシェル芸bot で出力できた方が良いという声があればこの限りではなく、シェル芸bot オーナーの意向に沿っていきたいと思います。

Docker イメージにドキュメント類を含めない仕組み

unminimize の処理の中に、/etc/dpkg/dpkg.cfg.d/excludes の削除があります。 このファイルは以下のような設定が入っています。

# Drop all man pages
path-exclude=/usr/share/man/*

# Drop all translations
path-exclude=/usr/share/locale/*/LC_MESSAGES/*.mo

# Drop all documentation ...
path-exclude=/usr/share/doc/*

# ... except copyright files ...
path-include=/usr/share/doc/*/copyright

# ... and Debian changelogs
path-include=/usr/share/doc/*/changelog.Debian.*

ubuntu wikiReducingDiskFootprint - Drop unnecessary files あたりで説明されている通り、path-include=... の記載により、dpkg がパッケージをインストールする際に、これらの指定にマッチするパスにファイルを配置しないようになっているようです。 そのため、/etc/dpkg/dpkg.cfg.d/excludes が入ったままの状態では、ドキュメントを含む deb パッケージを追加でインストールしても、ドキュメント類が配置されません。

おわりに

シェル芸bot の Docker イメージをいじくってたら、Ubuntu のこんな面白い仕掛けにたどり着いてしまいました。 楽しい機会を与えてくれたシェル芸界隈の皆さま、そしてシェル芸bot を運用しながら、毎度説明不足な私の Pull Request を見ていただいているふるつき氏に感謝です。

$ owari kan --giko -aso

| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
|        終        |
|    制作・著作    |
|   ̄ ̄ ̄ ̄ ̄ ̄ ̄  |
|        so        |
|_________|
    ∧∧ ||
   ( ゚д゚)||
    /   づΦ

(たのしい)