第46回シェル芸勉強会 大阪サテライト レポート

2/14(土) に開催された第46回シェル芸勉強会 大阪サテライト会場の様子をレポートします。

案内

福岡はお休み。

あと今回は箱根でもサテライト会場が開かれたようです。楽しそう。

今まで ATND で募集ページを作成していましたが、4月にサービス終了になるようなので、connpass に引っ越しました。 ATND の過去の募集ページも connpass に取り込みましたが、参加者などの情報は移せないようでした。 参加コメントの大喜利も消えてしまいますが、まぁシェル芸なんて書き捨てのものなので良いでしょう。

大阪サテライトの様子

東京会場では例年この時期は参加者数が減るそうですが、大阪は久々に募集人数を超える応募がありました。 あまり大人数になってしまうと、会場スタッフが確保できずにアタフタしてしまうので、今のところ募集枠の拡大は考えておらず、このくらいの人数でやっていければ良いなと思っています。 参加者10名中、4名の方が初参加でした。

ホワイトボードを使って Q8 の枝刈りをする様子。

LT は無く、東京の様子を見ていました。

おわりに

アルゴリズム事典からの出題をシェル芸で解くということで、また知らない awk の使い方を学ぶことができました。 上田先生が冒頭に話されていましたが、普段使わない頭に、たまに負荷をかけて問題を解くのは面白いですね。

参加いただいた方、運営に協力頂いた方、そして主催の上田先生、ありがとうございました。 次回は4月頃ですかね。またよろしくお願いします。

ダウトー。

第45回シェル芸勉強会 大阪サテライト レポート

12/28(土) に開催された第45回シェル芸勉強会 大阪サテライト会場の様子をレポートします。

案内

午前の部

元々午前の部は予定されていませんでしたが、ぷる(@butackle66)氏が JavaScript の非同期処理について、ストリーミング配信で講義してくれました。

シェルの世界とは異なり、JavaScript では GUI の様々デバイスや I/O を同時に安全に効率よく扱うため、シングルスレッドであったり、非同期処理という方法が提供されているんだと思います。 このような制約のある状況で処理することは普段あまりないので、聞いてていろいろ考えてみることになり、勉強になりました。ありがとうございます。

ぷる氏も講義中に話されていましたが、聞き手の直接の反応が見えない配信は、やっぱり結構不安になってしまいますね。 聞いている方はラジオ番組を聴きながら、同じ番組を聴いてるリスナーと Twitter でワイワイする感じで、結構良かったのですが。

大阪サテライトの様子

参加者は5名、うち3名が初参加でした。 初めましての方は、(いつものことですが)午後のシェル芸問題にほとんど手が出なかった模様。 普段から触ってないと難しいもんね...。

会場の WiFiSSID とパスワードを QR コード生成ワンライナーで表示してみたのですが、あまり馴染みのない文字列で、初参加者には通じませんでした。残念。

twitter.com

LT

www.youtube.com

「シェル芸のおかげでUnicodeに怯えず楽しめるようになった話」 - taka(@amanoese)さん

twitter.com

帰省先からリモートで発表していただきました。 発表で紹介された kana2ipa と、東京の LT で kanata さんが紹介された ivsteg は、早速シェル芸botに追加してもらいました。

「ワタナベシェル」 - たいちょー(@xztaityozx_001)さん

www.slideshare.net

午後の勉強会の問題にもなっていた noc を入力にも出力にも使って完全 nabe 化されたシェル。 本人も読めてなかったよこれ。

配信メモ

OBS で配信してるんですが、macOS を Catalina にアップデートしてから、画面のキャプチャがうまくいかなくなっていました。 Catalina から、ウィンドウ・画面をキャプチャするアプリケーションに対して、個別にシステム設定から画面収録を許可しなければならなくなったようですが、OBS がアプリケーションの一覧に出てこなくて困っていました。

qiita.com にあるように、ターミナルから OBS を起動し、ターミナルに対して画面収録を許可することで、回避できました。 ただこれだと、ターミナルから起動する全てのアプリが許可されるようで、あまり良くない気もしますが。

おわり

年末の忙しい時期に、皆さん集まっていただき、ありがとうございました。 楽しいシェル芸納めができました。来年もよろしくお願いします。

X11シェル芸

この記事はシェル芸 Advent Calendar 2019 12日目の記事です。 当初 Qiita に投稿していましたが、こちらに引っ越しました。

X11シェル芸とは

X Window System(X11)上のGUIアプリケーションを操作するシェル芸です。 こんなやつ。

デスクトップ版のLinuxディストリビューションxeyesを実行すると、マウスカーソルを追いかける目玉のアプリケーションが動きます。 このようなGUIアプリケーションを、シェル芸botのような、デスクトップのない環境で実行しようというチャレンジです。

準備

Ubuntuで、以下のパッケージをインストールします。

  • xvfb
    • X11の仮想フレームバッファを提供するコマンドで今回の主役
    • 物理的なディスプレイがなくても、コイツとメモリがあればマルチディスプレイも余裕だ
  • x11-apps
    • xeyesなどの楽しいX11アプリケーション詰め合わせ
  • x11-utils
    • X11環境を便利に使うツールのお得な詰め合わせ
    • ここではxwininfoを使う
  • xdotool
  • imagemagick
    • 画像処理なら任せろ

ウィンドウマネージャ等は必要ないので省きます。 Docker環境で試せるよう、Dockerfileを用意しておきました。

FROM ubuntu:19.10
RUN apt-get update \
  && DEBIAN_FRONTEND=noninteractive \
    apt-get install -y --no-install-recommends \
    xvfb x11-apps x11-utils xdotool imagemagick \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*

Dockerfileというファイル名で保存し、次のようなコマンドでDockerイメージをビルドできます。

$ docker image build -t shellgeiadv .

Dockerコンテナを起動します。実行するGUIアプリケーションのスクリーンショットを出力するため、./imagesをボリュームマウントしておきます。

$ docker container run -it --rm -v $(pwd)/images:/images shellgeiadv

仮想フレームバッファを準備する

この状態でxeyesを実行すると、ディスプレイが開けねーぞって怒られます。そりゃあそうです。

# xeyes
Error: Can't open display:

なので、Xvfbを使って、仮想的なディスプレイを用意してやります。

# Xvfb :1 -screen 0 320x240x8 &
[1] 8

:1はディスプレイサーバーの番号、-screenはディスプレイサーバーに紐付くスクリーン番号(0)の解像度(幅:320 x 高さ:240)x 色深度(8bit)の指定です。バックグラウンドで起動するため、&を付けています。 こんな極小ディスプレイはほとんどないと思いますが、仮想ディスプレイなら簡単に作れちゃいます。

X11アプリケーションは、DISPLAY変数に設定されたディスプレイサーバー番号にウィンドウを表示するため、Xvfbで作成した仮想ディスプレイの番号(:1)を設定しておきます。

# export DISPLAY=:1

xeyesを実行する

こちらもバックグラウンドで実行しておきます。

# xeyes &
[2] 11

ターミナルには何も表示されないため、動いているのかよくわかりませんが、psでプロセスを確認すると、ちゃんと動いているようです。

# ps
  PID TTY          TIME CMD
    1 pts/0    00:00:00 bash
    8 pts/0    00:00:00 Xvfb
   11 pts/0    00:00:00 xeyes
   12 pts/0    00:00:00 ps

xwininfoを使うと、仮想ディスプレイサーバーに配置されたウィンドウの位置が、なんとなくわかります。

# xwininfo -display :1.0 -root -tree

xwininfo: Window id: 0x4d (the root window) (has no name)

  Root window id: 0x4d (the root window) (has no name)
  Parent window id: 0x0 (none)
     1 child:
     0x20000a "xeyes": ("xeyes" "XEyes")  150x100+0+0  +0+0
        1 child:
        0x20000b (has no name): ()  150x100+0+0  +1+1

画面をキャプチャする

xwd(X Window System window dumping utility)を使って、ディスプレイのスクリーンキャプチャを取得することができます。 XWD形式のフォーマットで出力されますが、ImageMagickconvertで処理することができます。

# xwd -display :1 -root | convert xwd:- /images/xeyes.png

Dockerホストの./images/xeyes.pngに次のような画像が生成されていると思います。 f:id:horo1717:20200326012054p:plain

ウィンドウを操作する

xdotoolを使ってウィンドウを移動してみます。xdotoolでウィンドウを操作するには、ウィンドウIDを取得する必要があります。先のxwininfoより、xeyesのウィンドウIDは0x20000aと表示されましたが、環境によって変わる可能性があるため、xdotool searchを使って、ウィンドウ名で検索した結果を利用します。

# xdotool search --name xeyes
2097162

xeyesのウィンドウサイズは、先のxwininfoより、150x100となります。 また、xdotoolで次のように取得することもできます。

# xdotool getwindowgeometry 0x20000a
Window 2097162
  Position: 0,0 (screen: 0)
  Geometry: 150x100

これらの座標を元に適当に計算し、ウィンドウをディスプレイの中心に配置してみます。

# xdotool search --name xeyes | xargs xdotool getwindowgeometry | awk -F'[x ]' 'NR==1 {printf $2" "} NR==3 {print (320-$4)/2, (240-$5)/2}' | xargs xdotool windowmove

スクリーンキャプチャを取得してみると、寄り目が現れます。

# xwd -display :1 -root | convert xwd:- /images/xeyes_center.png

f:id:horo1717:20200326012200p:plain

シェル芸botで実行する

ここまでの内容を、適当にスクリプトとして実行します。バックグラウンドで動作するコマンドを連続して実行すると、前のコマンドの実行が間に合わないことがあるため、適当にsleepを挟んでおくと良いでしょう。

Xvfb :1 -screen 0 320x240x8 & sleep 1
export DISPLAY=:1
xeyes & sleep 1
xdotool search --name xeyes \
| xargs xdotool getwindowgeometry \
| awk -F'[x ]' 'NR==1 {printf $2" "} NR==3 {print (320-$4)/2, (240-$5)/2}' \
| xargs xdotool windowmove & sleep 1
xwd -display :1 -root | convert xwd:- /images/x.png

シェル芸botは、バックグラウンドプロセスが動きっぱなしでも実行結果ツイートしてくれますが、SGWebで実行する場合は、バックグラウンドプロセスも終了させておく必要があるため、timeoutコマンドで指定秒数後に停止するよう仕込んでおくと良いでしょう。

timeout 5 Xvfb :1 -screen 0 320x240x8 & sleep 1
DISPLAY=:1 timeout 3 xeyes & sleep 1
xdotool search --name xeyes \
| xargs xdotool getwindowgeometry \
| awk -F'[x ]' 'NR==1 {printf $2" "} NR==3 {print (320-$4)/2, (240-$5)/2}' \
| xargs xdotool windowmove & sleep 1
xwd -display :1 -root | convert xwd:- /images/x.png

おわりに

シェル芸botでxeyesを表示するだけではあまり面白くないですが、GUI環境をコマンドラインから扱えると、ちょっと嬉しいことがあるかもしれません。たとえば、GUIアプリケーションをデスクトップに並べてパズルとして遊ぶとか。そういえば昔、LinuxサーバーにXvfbとLibreOfficeを入れて、sofficeコマンドを使ってヘッドレスでOfficeドキュメントをPDFに変換していたこともありましたね。そんな感じで、GUI環境もコマンドラインから扱えると、作業が捗りそうです。 楽しいシェル芸ライフを。

第44回シェル芸勉強会 大阪サテライト レポート

10/26(土) に開催された第44回シェル芸勉強会 大阪サテライト会場の様子をレポートします。

案内

今回松江はお休み。 1年ぶりに福岡サテライトが開催されました。

大阪サテライトの様子

参加者は4名、いつも参加されているメンバーでした。

久々の午前の部はぷる氏による JavaScript のオブジェクトについての講義。 個人的にはとても苦手意識のある JavaScript について解説していただきました。 JavaScript がこんなにややこしい仕様になっているのは、長い歴史の積み重ねがあるからでしょうか...?

講義中、いつもはうんこばかり流れているシェル芸タイムラインに、とても有用な情報が流されていました。 講師からの一方向のお話ではなく、参加者皆の知見が集まるのは素晴らしいです。

午後の部の前半4問は、数独をシェル芸で段階的に解いていくものでしたが、2問目の難易度がとても高かったように思います。 行指向でデータを扱うため、前後の行にあるデータも利用できるように工夫することが求められているようでした。

LT

www.youtube.com

「-(横線)難読化シェル芸」 - MSRさん

speakerdeck.com

Unicode には 64 以上もの横線が収録されているそうです。大体一緒だろ。

横線を利用した新たなエンコード手法と、その実装の horizon コマンドを提案されました。

「structured-text-tools の紹介」 - 小原 一哉さん

dbohdan/structured-text-tools にまとめられている構造化テキスト処理ツールの中から、3つをピックアップして紹介されました。

発表内では csvquote のメリットが少し理解しづらかったのですが、後で調べてみてとても有用だなと思ったので、ついでに紹介してみます。

CSV では、"..." (ダブルクォート) 内の , (カンマ) をフィールドセパレータとして、改行をレコードセパレータとして扱わないようですが、そのようなデータを、awk, sort, cut のような UNIX コマンドで扱おうとすると、少し困ります。

例えば、以下のようなデータを2フィールド目でソートしたい場合。

$ cat sample.csv
unko,3
"u,nk,o",5
"un
ko",2

csvquote を通すと、ダブルクォート内のカンマは 0x1f (US; ユニット区切り)、改行は 0x1e (RS; レコード区切り) に置換されます。

$ cat sample.csv | csvquote | xxd
00000000: 756e 6b6f 2c33 0a22 751f 6e6b 1f6f 222c  unko,3."u.nk.o",
00000010: 350a 2275 6e1e 6b6f 222c 320a            5."un.ko",2.

この状態で sort を実行し、csvquote -u で置換された文字を元に戻すことができるようです。

$ cat sample.csv | csvquote | sort -t',' -k2n | csvquote -u
"un
ko",2
unko,3
"u,nk,o",5

ちょっと扱い辛かった CSV がとても扱いやすくなって良い感じです。

紹介された GitHub リポジトリには、他にも便利そうなツールがたくさん紹介されていました。

「柿と杮(かきとこけら)」 - たいちょーさん

www.slideshare.net

かきとこけら。一緒だろ(2回目)。

でバイナリを表現する手法と、その実装の kakikokera コマンドを提案されました。 こけらと同じく、肺の字のつくりは市ではないそうです。 しらなんだ。


LT で紹介されたコマンド類は、早速シェル芸botに追加してもらいました 🙌

おわり

久々に終日の勉強会となりとても疲れましたが、学びの多い一日でした。 講師の方、LT発表された方、参加された皆さま、ありがとうございました。 次回は年末頃でしょうか。またよろしくお願いします。

第43回シェル芸勉強会 大阪サテライト レポート

8/10(土) に開催された第43回シェル芸勉強会 大阪サテライト会場の様子をレポートします。

案内

大阪サテライトの様子

今回はいつもの場所が利用できなかったため、大阪工業大学さんの教室をお借りして開催しました。 参加者は6名、うち1名の方が初参加でした。

全員初心者宣言をする大阪サテライト民。

勉強会前半の問題はけっこう解けている人もいたのですが、休憩を挟んで後半は難しかったです。 解き方のヒントになりそうなものは、シェル芸botのツイートでちらほら見たことがあるのですが、実際に手を動かして取り組んでいないと、ぱっと手段が思いつかないですね。

LT

今回も2つ発表していただきました。 どちらもとても面白くてヤバい発表だったので、是非動画で見てください。

録画

www.youtube.com

「難読化PowerShell芸入門」 - たいちょー さん

www.slideshare.net

シェルを触っていると難読化してしまう病気を患っているらしい、ゆるふわお嬢様系難読化シェル芸人さん。 今回は PowerShell での難読化について語っていただきました。

料理番組のように「できましたー」と手際よく難読化されていくコマンド。 最終的に bashPowerShell の難読化が合わさってますます意味分からんぞ...。

「VUIでシェル芸を実行できるようにしてみた」 - taka さん

speakerdeck.com

アクセラ(アレクサと発音すると Alexa が反応してしまうためこう呼んでいた)に任意のシェル芸を実行させるための、厨二めいた呪文の詠唱がとんでもなくやばかったです。 ゲラゲラ笑いたいのに、アクセラの邪魔をしちゃダメなので、笑いをこらえるのにみんな必死。 すごく真面目にイタい呪文を唱える、最高の LT でした。

そのた

勉強会中にコマンドを追加した

勉強会 の Q3 で IPv4 アドレスの10進2進変換問題が出ました。 bcdc コマンドで基数変換ができるのですが、ipcalc という便利なコマンドがあれば一発で求めることができるそうです。 シェル芸botには ipcalc は入ってなかったのですが、せっかくふるつきさんから ShellgeiBot-Image リポジトリのコミット権をもらってるので、勉強会中にしれっと追加 しちゃいました。

おわり

終始とても楽しい勉強会でした。 主催の会長さん、参加いただいた皆さん、LT で発表していただいた方、運営を手伝って頂いた方、会場を貸して頂いた大阪工業大学さん、ありがとうございました。

$ owari kan -g -a so

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

次回は午前の部が企画されているそうで、楽しみです。 次回もよろしくお願いします!

AWSでDockerコンテナからメタデータサービスへのアクセスをブロックする

概要

環境

  • Ubuntu 18.04.1 LTS (ami-0eeb679d57500a06c)
  • Docker 18.09.7

Docker セットアップ

[host] # apt-get update
[host] # apt-get install docker.io
[host] # systemctl start docker
[host] # systemctl enable docker
[host] # gpasswd -a ubuntu docker  # デフォルトの ubuntu ユーザーで docker コマンドを実行できるように; 設定後再ログイン

確認

  • 何も制限しない状態で Docker コンテナからメタデータサービスへのアクセスを確認してみる
[host] $ docker run -it --rm ubuntu:18.04
[container] # apt-get update
[container] # apt-get install netcat
[container] # nc -vz 169.254.169.254 80
instance-data.ap-northeast-1.compute.internal [169.254.169.254] 80 (?) open    # 接続できた

ファイアウォールを設定する

  • docker のネットワーク設定確認
[host] $ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
6471516562dc        bridge              bridge              local
305df41ba1c0        host                host                local
5ec5bac00e37        none                null                local
  • Docker コンテナ用に 172.17.0.0/16 がブリッジネットワークとして設定されている
$ docker network inspect bridge | jq '.[].IPAM'
{
  "Driver": "default",
  "Options": null,
  "Config": [
    {
      "Subnet": "172.17.0.0/16"
    }
  ]
}
  • iptables のルールを確認
    • Ubuntu では ufw 等のファイアウォール設定ツールも用意されているが、ここでは iptables を利用する (単純に慣れてるので)
    • filter テーブルの FORWARD チェーンで、DOCKER-USER -> DOCKER-ISOLATION-STAGE-1 -> DOCKER-ISOLATION-STAGE-2 -> DOCKER の順に参照される
[host] # iptables -nL
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy DROP)
target     prot opt source               destination
DOCKER-USER  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER-ISOLATION-STAGE-1  all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain DOCKER (1 references)
target     prot opt source               destination

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination
DOCKER-ISOLATION-STAGE-2  all  --  0.0.0.0/0            0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
target     prot opt source               destination
DROP       all  --  0.0.0.0/0            0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Chain DOCKER-USER (1 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0
  • iptables の設定を永続化するため、iptables-persistent をインストール
    • 途中で聞かれる選択肢で Yes を選択すると、/etc/iptables/rules.v4, /etc/iptables/rules.v6 に現在の設定が保存される
[host] # apt-get install iptables-persistent
  • DOCKER-USER チェーンの先頭に、docker ブリッジネットワーク (172.17.0.0/16) からリンクローカルアドレス (169.254.0.0/16) へのアクセスを破棄するルールを一時的に追加する
[host] # iptables -I DOCKER-USER 1 -s 172.17.0.0/16 -d 169.254.0.0/16 -j DROP
[host] # iptables -nL DOCKER-USER
Chain DOCKER-USER (1 references)
target     prot opt source               destination
DROP       all  --  172.17.0.0/16        169.254.0.0/16
RETURN     all  --  0.0.0.0/0            0.0.0.0/0
  • Docker コンテナからアクセス確認
    • リンクローカルへのアクセスはブロックされる
    • それ以外のアクセスは通る
[container] # nc -w 1 -vz 169.254.169.254 80
instance-data.ap-northeast-1.compute.internal [169.254.169.254] 80 (?) : Connection timed out
[host] # /etc/init.d/netfilter-persistent save

$ 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        |
|_________|
    ∧∧ ||
   ( ゚д゚)||
    /   づΦ

(たのしい)