テストを完走したスクリプトが本番環境で動かない!などの不安を和らげる数行のコードで、個人的によく使う 3つを紹介します。
1. 環境変数 $PATH
systemd から実行したら動かないなどの問題が起きないように、環境変数$PATH
の値を最初に整えます。スクリプト内で各コマンドをフルパスで書くより、環境変数をテスト環境と同じにした方が安心です。
for _path in $(echo "/usr/local/sbin:/usr/local/bin:/usr/sbin:/opt/myapp" | tr ':' '\n'); do
echo ${PATH} | tr ':' '\n' | grep -q "^${_path}$" || PATH+=":${_path}"
done
現在の$PATH
に含まれないパスが"/usr/local/sbin:/usr/local/bin:/usr/sbin:/opt/myapp"
の中にあれば$PATH
に追加されます。区切り文字の:
を改行に置換して各パスを行に区切ることでgrep
での比較をしやすくしています。
(重複やべき等を気にしなければ、単にPATH+=
で追加すればいいだけですが)
2. 多重起動防止
ファイルなどのリソースを操作するスクリプトで安心できるようになります。
(( $$ == $(pgrep -fo "$0") )) || exit 1
「同じコマンドライン文字列で実行された最も古いプロセス」が現在のプロセスなら通過、違っていたら多重起動と判定して異常終了します。実行時のコマンドライン文字列がいつも同じであることが条件になります。
3. 終了処理
trap
で指定した関数on_exit()
が終了時に実行されます。とりあえず書いておけば、スクリプト作成中に思いついた終了処理をすぐに追加できます。
function on_exit() {
# $1: exit code
}
trap 'on_exit $?' EXIT
スクリプト内では、エラーで終了したいコマンドや関数の呼び出しをsomecommand || exit $?
のように書きます。
関数on_exit()
では終了コードの値を見て、正常終了時/異常終了時/共通の処理をそれぞれ記述することができます。
function on_exit() {
if (($1 == 0)); then
echo "Completed."
else
echo "Failed ($1)." >&2
fi
echo "Bye."
}
+1.
sh が bash にリンクされているかどうかに関係なく、使用するシェルは明示的に宣言します。
#!/bin/bash
参考リンク
- 「UNIX & Linux コマンド・シェルスクリプト リファレンス」 https://shellscript.sunone.me/
- 「“応用力”をつけるためのLinux再入門」 https://www.atmarkit.co.jp/ait/series/3016/