「ソフトウェアデザイン2020年1月号」を読んでいるのですが、その中に次の一節がありました。
GitLab のCI に関する部分は.gitlab-ci.yml に書き、単独でも実行できる内容はシェルにまとめて、scriptで呼び出すのがお勧めです。
そうすると、.gitlab-ci.ymlに必要な事項だけがまとまって見やすくなるはずです。
しかし、シェルスクリプトにまとめてしまうと実行経過が見えなくなったりするので、シェルスクリプト内で実行過程を標準出力に出力するか、シェルスクリプトのshebang注C に「set -x」または
「set -xe」を付けることをお勧めします。
GitLab特集の記事ですが、CI上で実行するシェルスクリプトには、「set -x」または「set -xe」を付けようという内容です。
なぜ「set -x」または「set -xe」なのか、少し深堀ってみます。
これが理解できるようになると、CI以外の環境であっても、重要なオプションであることがわかります。
なお本記事では、「/bin/bash」を使用しております。
errexit -e:パイプやサブシェルで実行したコマンドが1つでもエラーになったら、直ちにシェルを終了する
https://www.atmarkit.co.jp/ait/articles/1805/10/news023.html より
シェルスクリプトを実行する際に「-e」を追加すると、エラーが起きたコマンドの時点でスクリプトが終了するようになります。
#!/bin/bash -e
# 存在しないファイルを閲覧しようとする
cat ./test1
# 以下は実行されない
cat ./test2
cat ./test3
$ /bin/bash -e test.sh
cat: ./test1: No such file or directory
$ echo $?
1 # 1が出力されるため、test.shが成功しなかったことがわかります
または「set -e」を使っても、同様にエラーが発生した時点で処理を止めることができます。
#!/bin/bash
# -o:シェルオプションを有効にする
set -e
# 存在しないファイルを閲覧しようとする
cat ./test1
# 以下は実行されない
cat ./test2
cat ./test3
# +o:シェルオプションを無効にする(-oによる設定を打ち消す)
set +e
自力で頑張る場合は、コマンドの終了ステータスを判定することによって、制御が可能です。
#!/bin/bash
cat ./test1
# コマンドの終了ステータスが「0」以外であれば、コマンドは成功していない
cmdstatus=$?
if [ $cmdstatus -ne 0 ]; then
echo "command error!!"
# 必要なら、ここで異常系フローの後処理ができる
# 実行を終了させる
exit $cmdstatus
fi
# 以下は実行されない
cat ./test2
cat ./test3
xtrace -x: トレース情報として、シェルが実行したコマンドとその引数を出力する。情報の先頭にはシェル変数PS4の値を使用
https://www.atmarkit.co.jp/ait/articles/1805/10/news023.html より
シェルスクリプトを実行する際に「-x」を追加すると、シェルが実行したコマンドを出力します。
#!/bin/bash -x
cat ./test1
cat ./test2
cat ./test3
$ /bin/bash -x test.sh
+ cat ./test1
cat: ./test1: No such file or directory
+ cat ./test2
cat: ./test2: No such file or directory
+ cat ./test3
cat: ./test3: No such file or directory
スクリプト内に「set -x」を記述する場合は、トレースしたい箇所の前後に追加します。
#!/bin/bash
set -x
cat ./test1
cat ./test2
cat ./test3
set +x
これら2つのオプションは、組み合わせて使うことができます。
「-e」オプションによりエラーが起きた時点でスクリプトが終了しますが、「-x」オプションにより実行コマンドが逐一出力されるため、開発中やデバッグ時はとくに便利です。
#!/bin/bash -ex
# 存在しないファイルを閲覧しようとする
cat ./test1
# 以下は実行されない
cat ./test2
cat ./test3
$ /bin/bash -ex test.sh
+ cat ./test1
cat: ./test1: No such file or directory
# 「cat ./test1」でエラーが起きて失敗したことが、ひと目でわかる
CI上でシェルスクリプトを動かす場合、基本的には自分の手の届かない範囲でスクリプトが実行さます。
でもシェルスクリプトの実行にデバッグオプションを付けておけば、CIのログを確認することで、スクリプトの実行確認やエラーの追跡がとてもやりやすくなります。
アプリケーションのプログラミングでは、「try〜catch」をはじめとするエラー制御が必要であるという認識は普及しています。
一方で、シェルスクリプトにおいてもエラー処理や異常系を考慮して開発する必要があります。
これは意外と抜け落ちやすいので、忘れないようにしましょう(・・という戒めを込めた、自分向けの記事だったりします)。
ちなみに「ソフトウェアデザイン2020年1月号」にはGitLab特集があるのですが、私もGitLabは好きです。
実際に業務で使ってますが、CIがとても書きやすいです。
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント