Dockerfileで複数行を改行付きでechoする際にハマったので共有しておきます

Bash, Docker

はじめに

最近Dockerfileを作成したときに、 RUN コマンド内で改行付き情報を echo したかったのですが、多少ハマってしまったので共有します。

検証環境

$ uname -moi
x86_64 MacBookPro11,4 Darwin

$ docker --version
Docker version 18.09.2, build 6247962

経緯

Dockerイメージ作成のために「Dockerfile」を作成しました。

その際に、.bashrcファイルにaliasを追加したかったので、以下のように記述しました。
(ネット上に転がっている情報を参考にしました。)

FROM centos:centos7

RUN echo $"\n\
alias ll='ls -l'\n\
alias la='ls -a'\n\
alias lla='ls -l -a'\n\
" >> /root/.bashrc

ポイントとしては、 echo コマンドの引数として渡す情報の各行末に \n\ と記述すること。これにより以下の命令と同等の出力ば行われるとのことでした。

$ echo $"
alias ll='ls -l'
alias la='ls -a'
alias lla='ls -l -a'
" >> /root/.bashrc

試してみると...

イメージをビルドし、起動してみます。

# ビルド
$ docker build . --tag=genzouw/test

# 起動
$ docker run --rm -it genzouw/test bash
bash: nalias: command not found
[root@19775d30756e /]#

一応起動はできたのですが、エラーが発生しています。
~/.bashrc を確認してみます。

[root@19775d30756e /]# tail ~/.bashrc

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi
\nalias ll='ls -l'\nalias la='ls -a'\nalias lla='ls -l -a'\n

最終行の alias の内容がめちゃくちゃですね。
うまく改行できていないことがわかります。

echo -e で対処する

「Dockerfile」を以下のように書き換えることで対処できました。

FROM centos:centos7

RUN echo -e $"\n\
alias ll='ls -l'\n\
alias la='ls -a'\n\
alias lla='ls -l -a'\n\
" >> /root/.bashrc

ビルドしてイメージを作成後、起動すると今度は問題なく動作しました。

echo -e とは?

マニュアルを引いてみる。

$ man echo

一部抜粋すると以下のように書かれている。

    -e     enable interpretation of backslash escapes

    ...

    If -e is in effect, the following sequences are recognized:

    ...

    \n     new line

-e オプションを付けないと \n を改行として取り扱ってくれないようですね。

ひとこと

環境に依存するのかな?
なぜ他の方々は -e オプション無しで問題が起きてないのか。

Bash, Docker