リポジトリの便利スクリプトを /scripts
に入れるときのテクニックを紹介します。
shebang を書く
# !/bin/bash
1 行目をこのようにするとで、起動するシェルを Bash に揃えることができます。Linux を対象にするときは Bash をターゲットに書くことをオススメします。 Mac やコンテナ内で動かす可能性がある場合は /bin/sh
を対象にすることもあります。
他に #!/usr/bin/env python3
も使うことがあります。依存が 1 つ増えることになるのでチームの状況を見ながら選択します。
カレントディレクトリを揃える
# 起動したファイルの場所 1 つ上(/scripts ならリポジトリのルート)に移動する
cd $(dirname $0)/..
shebang の次にこの行を書くことが多いです。 README に「○○に移動してから起動してください」と書くより優しいスクリプトになります。
標準エラー出力にログ
標準出力には結果を出力して、途中のデバッグログやエラーログは標準エラー出力に出すようにすることで、結果をパイプで繋いで再利用できるように保ちましょう。
インクルードガード
複数のスクリプトで共通して利用するなら /scripts/lib
あたりにまとめると良いでしょう。 source で取り込んで利用します。ただし、多重に取り込まれても良いように、先頭で 2 回目以降の実行は拒否します。
[[ -n "$__LOGGER_SH" ]] && return || readonly __LOGGER_SH=1
例えば、簡易的なロガーを作るとすると下記のようになります。
# !/bin/bash
[[ -n "$__LOGGER_SH" ]] && return || readonly __LOGGER_SH=1
# 0: DEBUG
# 1: INFO
# 2: WARN
# 3: ERROR
declare -r LOG_LEVEL=${LOG_LEVEL:-1}
log_debug() {
if (( $LOG_LEVEL <= 0 )); then
echo -e "\033[1;40m DEBUG \033[00m $*"
fi
}
log_info() {
if (( $LOG_LEVEL <= 1 )); then
echo -e "\033[1;44m INFO \033[00m $*"
fi
}
log_warn() {
if (( $LOG_LEVEL <= 2 )); then
echo -e "\033[1;43m WARN \033[00m $*"
fi
}
log_error() {
if (( $LOG_LEVEL <= 3 )); then
echo -e "\033[1;41m ERROR \033[00m $*"
fi
}
大規模化しそうなら別プロジェクトに切り出す
シェルスクリプトは可読性が低くなりやすいので、複雑化する気配を感じたら適切にツールのプロジェクトとして切り出しましょう。