DockerfileのRUNでExpectスクリプトを実行して、keyboard-configurationパッケージのインストールを自動化する例を記載します。ただし、結論を言えば、Expectスクリプトは別ファイルで用意すべきです。
Table of Contents
1 keyboard-configurationパッケージ
keyboard-configurationパッケージをインストールするとキーボードレイアウトをインタラクティブに設定できます。
keyboard-configurationパッケージの応答は/etc/default/keyboardを用意すればスキップできますが、console-setupパッケージのようにできないケースもあるので、ここではExpectスクリプトを使って応答を自動化します。
2 Expectスクリプトの場合
keyboard-configurationのインストールを自動化するには以下のExpectスクリプトが必要なります。
- "[More]"に対して"\n"を送信します。Expectスクリプトは[と]に対して\\\でエスケープする必要があります。
- "Country of origin for the keyboard: "に対して"50\n"を送信します。
- "Keyboard layout: "に対して"1\n"を送信します。
#!/usr/bin/env expect
set timeout -1
spawn apt-get install -y keyboard-configuration
expect {
"\\\[More\\\]" { send "\n"; exp_continue; }
"Country of origin for the keyboard: " { send "50\n"; }
}
expect {
"\\\[More\\\]" { send "\n"; exp_continue; }
"Keyboard layout: " { send "1\n" }
}
expect eof
[More]はキーボード一覧表示がターミナルソフトの高さに到達した場合に表示されます。
Configuring keyboard-configuration ---------------------------------- The layout of keyboards varies per country, with some countries having multiple common layouts. Please select the country of origin for the keyboard of this computer. [More]
3 シェルスクリプトの場合
シェルスクリプトにすると以下のようになります。
- ダブルコーテーション内の\\\が\に変換されます(シングルコーテーションの場合は\\が\に変換されますが、シェル変数を代入できません)。
- printfの場合はシェルでの改行が改行文字として扱われます。
#!/bin/sh
apt-get update -y
apt-get install -y expect
printf "
set timeout -1
spawn apt-get install -y keyboard-configuration
expect {
\"\\\\\\\\\[More\\\\\\\\\]\" { send \"\\\n\"; exp_continue; }
\"Country of origin for the keyboard: \" { send \"50\\\n\"; }
}
expect {
\"\\\\\\\\\[More\\\\\\\\\]\" { send \"\\\n\"; exp_continue; }
\"Keyboard layout: \" { send \"1\\\n\" }
}
expect eof
" | expect
4 Dockerfileの場合
Dockerfileにすると以下のようになります。
- Dockerfileは行末に\をつけることで複数行に処理を記載できます。
- 複数行に処理を記載してもDockefileでの改行は処理に渡されません。printfの文字列の場合は改行文字の\nを明記する必要があります。複数のコマンドを記載する場合はセミコロンや&&で繋ぐ必要があります。
- [More]の処理は不要になるようです(-tオプションなしでTERMを空にしている?)。
FROM ubuntu:16.04
RUN apt-get update -y && \
apt-get install -y expect && \
printf "\
set timeout -1\n\
spawn apt-get install -y keyboard-configuration\n\
expect {\n\
\"\\\\\\\\\[More\\\\\\\\\]\" { send \"\\\n\"; exp_continue; }\n\
\"Country of origin for the keyboard: \" { send \"50\\\n\"; }\n\
}\n\
expect {\n\
\"\\\\\\\\\[More\\\\\\\\\]\" { send \"\\\n\"; exp_continue; }\n\
\"Keyboard layout: \" { send \"1\\\n\" }\n\
}\n\
expect eof\n\
" | expect
5 まとめ
ExpectスクリプトをDockerfileのRUNで直接使おうとすると余計なコストが掛かります。Expectスクリプトを別に用意し、DockerfileのCOPYやADDでコンテナにコピーしてから実行するようにしましょう。
FROM ubuntu:16.04 RUN apt-get update -y && apt-get instal -y expect COPY keyboard-configuration.exp / RUN expect keyboard-configuration.exp