SC2115: ガードされていない変数による危険なrm -rf

空の変数によるrm -rfの壊滅的な削除を防止。${var:?}、set -u、ディレクトリガードを使った安全なパターンを解説します。

Error Handling

詳細な説明

rm -rf変数の罠

シェルスクリプトで最も危険なパターンの一つは、空または未設定の可能性がある変数でrm -rfを使用することです。空の変数は何にも展開されず、意図したよりもはるかに多くを削除する可能性があります。

壊滅的なシナリオ

# DEPLOY_DIRが未設定または空の場合:
rm -rf $DEPLOY_DIR/*
# 次のようになる: rm -rf /*
# システム上のすべてを削除!

rm -rf "$DEPLOY_DIR"/old
# 次のようになる: rm -rf ""/old -> rm -rf /old

安全なパターン

パターン1: ${var:?}を使用

rm -rf "${DEPLOY_DIR:?DEPLOY_DIRが設定されていません}"/old_release
# DEPLOY_DIRが未設定または空の場合、エラーメッセージで終了

パターン2: 明示的なチェック

if [ -z "$DEPLOY_DIR" ]; then
  echo "エラー: DEPLOY_DIRが設定されていません" >&2
  exit 1
fi
rm -rf "$DEPLOY_DIR"/old_release

パターン3: set -u(nounset)

set -u
rm -rf "$DEPLOY_DIR"/old_release
# DEPLOY_DIRが未設定の場合終了(ただし空の場合は終了しない!)

パターン4: 絶対パスチェック

# パスが妥当かを検証
case "$DEPLOY_DIR" in
  /home/deploy/*|/opt/app/*|/var/www/*)
    rm -rf "$DEPLOY_DIR"/old_release
    ;;
  *)
    echo "エラー: 予期しないDEPLOY_DIR: $DEPLOY_DIR" >&2
    exit 1
    ;;
esac

多重防御

最も安全なアプローチは複数のガードを組み合わせます:

set -euo pipefail
: "${DEPLOY_DIR:?必須}"
[[ "$DEPLOY_DIR" == /opt/app/* ]] || { echo "不正なパス" >&2; exit 1; }
rm -rf "$DEPLOY_DIR"/old_release

ユースケース

デプロイスクリプト、クリーンアップcronジョブ、CI/CDパイプライン、変数パスに基づいてファイルを削除するすべての自動化。本番環境でのデータ損失防止に重要です。

試してみる — Shell Script Linter

フルツールを開く