CodeBuild上でシェルスクリプトがうまく動かないときの対処法

CodeBuild上でシェルスクリプトを実行させたい場面がありましたが、正常に動作せずにハマったので、その原因と解決策を紹介したいと思います。
2018.11.14

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

どうも!大阪オフィスの西村祐二です。

みなさん、CodeBuild使ってますでしょうか。

コンテナ上でプログラム実行可能なマネージドサービスで、実行時間も最大8時間と長く、デプロイ処理だけじゃなくバッチ的な処理にも利用できてとても便利なサービスです。

そんな、CodeBuild上でシェルスクリプトを実行させたい場面がありました。

mac上ではスクリプトが正常に動作していたいのに、下記図のようにCodeBuild上で実行しようとするとエラーとなり、正常に動作しないということがありました。

今回はこの解決策を紹介したいと思います。

なんでうまく動かないのか

今回、利用したコンテナイメージはCodeBuildで管理されているコンテナを利用しました。

このコンテナイメージは、「Ubuntu」で動いています。

私知らなかったのですが、

Ubuntuの「/bin/sh」はbashではなく「dash」が動いています。

しかも、Ubuntuのバージョン6.10以降はログインのシェルは「bash」にしたまま、デフォルトのシェルを「bash」から「dash」に変わったそうです。

つまり、bashではなく、dashというシェルが動いているため、未対応の文法、コマンドでエラーとなったということになります。

dashについては下記を参照ください。

https://ja.wikipedia.org/wiki/Debian_Almquist_shell

どうやったらうまく動くのか

いくつか方法があります。

方法1:Shebangを「/bin/bash」として実行する

- sh ./test.sh
↓
- bash ./test.sh

または、スクリプト内の上部のShebangを「#!/bin/bash」として

- chmod +x ./test.sh
- ./test.sh

方法2:dashに対応する構文に置き換える

例えば、sourceコマンドはdashでは利用できませんが、「.」で代用可能です。

https://wiki.ubuntu.com/DashAsBinSh#source

方法3:「/bin/sh」をdashからbashにかえる

sudo dpkg-reconfigure dashを実行して「/bin/sh」を「bash」にかえることができます。

が、これは手動で作業が必要になります。

なのでスクリプト化して実行します。

下記がスクリプト化したものです。

change_shell.sh

# make /bin/sh symlink to bash instead of dash:
echo "dash dash/sh boolean false" | debconf-set-selections
DEBIAN_FRONTEND=noninteractive dpkg-reconfigure -p low dash

下記のように、「change_shell.sh」実行後は「/bin/sh」が「bash」にかわり、bashのコマンドが利用できるようになります。

「source」コマンドを使って環境変数の更新も可能になります。

buildspec.yml

  .
  .
  .
  pre_build:
    commands:
      - sh ./change_shell.sh
      - sh ./assume.sh
      - source ./envs.sh
      .
      .
      .

さいごに

いかがだったでしょうか。

CodeBuild上でシェルスクリプトがうまく動かないときの対処法を紹介しました。

誰かの参考になれば幸いです。