$ man シェル芸botのman
はじめに
普通の Linux 環境では、$ man コマンド
のように実行することで、コマンドのマニュアルを見ることができますが、シェル芸bot で man
コマンドを実行しても、(2019.7.17 時点では)マニュアルを見ることができません。
bash というマニュアルはありません
— シェル芸bot (@minyoruminyon) July 17, 2019
マニュアルページが利用できない場合のヘルプについては 'man 7 undocumented'を見てください。 https://t.co/HztEnGCm2S
これは、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
を実行すると、概ね以下のような処理が実行されます。
/etc/dpkg/dpkg.cfg.d/excludes
にある、パッケージ除外設定ファイルを削除して無効化apt-get update
,apt-get upgrade
を実行し、パッケージを更新/usr/share/man/
,/usr/share/doc/
,/usr/share/locale/
以下にファイルを配置するパッケージ類を(シェルワンライナーごりごりで)検索し、対象のパッケージを再インストール/usr/bin/man.REAL
に待避させてあったman
のバイナリを/usr/bin/man
に戻す
あとは、apt-get
で man-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 wiki の ReducingDiskFootprint - Drop unnecessary files あたりで説明されている通り、path-include=...
の記載により、dpkg がパッケージをインストールする際に、これらの指定にマッチするパスにファイルを配置しないようになっているようです。
そのため、/etc/dpkg/dpkg.cfg.d/excludes
が入ったままの状態では、ドキュメントを含む deb パッケージを追加でインストールしても、ドキュメント類が配置されません。
おわりに
シェル芸bot の Docker イメージをいじくってたら、Ubuntu のこんな面白い仕掛けにたどり着いてしまいました。 楽しい機会を与えてくれたシェル芸界隈の皆さま、そしてシェル芸bot を運用しながら、毎度説明不足な私の Pull Request を見ていただいているふるつき氏に感謝です。
$ owari kan --giko -aso | ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄| | 終 | | 制作・著作 | |  ̄ ̄ ̄ ̄ ̄ ̄ ̄ | | so | |_________| ∧∧ || ( ゚д゚)|| / づΦ
(たのしい)