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

Bash, Docker

はじめに

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

「2019-07-17 追記」コメント欄より

コメントを下さった Nig さん、ありがとうございます。勉強になりました。

以下のような構文を利用する際に、シングルクォーテーション( ' )で記述しないといけない部分がダブルクォーテーション( " )になっていたことが原因とのことでした。

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

※上記のスタイル以外で記述したい方は、当エントリを読み進めいただく意義はあるかと思います。

検証環境

$ 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

Posted by genzouw