SC2154: シェルスクリプトで参照されているが代入されていない変数

事前代入なしで使用される変数を検出。set -u、デフォルト値、入力検証で初期化されていない変数からのバグを防止する方法を解説します。

ShellCheck Patterns

詳細な説明

初期化されていない変数のバグ

代入されたことのない変数を使用することは、シェルスクリプトで最も一般的なバグの原因の一つです。ほとんどのプログラミング言語とは異なり、bashはデフォルトで未設定の変数に対してエラーを発生させません。暗黙的に空文字列に展開されます。

サイレントなバグ

# 変数名のタイプミス
databse_url="postgres://..."
echo "$database_url"  # 空!(タイプミス: databse vs database)

# 忘れられた代入
if [ "$ENV" = "production" ]; then
  deploy_target="/opt/app"
fi
cd "$deploy_target"  # ENVがproductionでない場合、空!

set -uによる検出

#!/usr/bin/env bash
set -u

echo "$UNSET_VAR"
# bash: UNSET_VAR: unbound variable

安全なデフォルト値

変数が正当に未設定の可能性がある場合、パラメータ展開を使用:

# 未設定の場合デフォルトを使用
log_level="${LOG_LEVEL:-info}"
port="${PORT:-3000}"
config_file="${CONFIG_FILE:-/etc/app/config.yml}"

入力検証

スクリプト引数は早期に検証:

#!/usr/bin/env bash
set -euo pipefail

if [ $# -lt 2 ]; then
  echo "Usage: $0 <source> <destination>" >&2
  exit 1
fi

source_dir="$1"
dest_dir="$2"

未設定と空の違い

var=""       # 設定済みだが空
unset var    # 未設定

# set -uは未設定のみキャッチ、空はキャッチしない
set -u
echo "$var"  # var=""の場合OK(空は問題なし)
echo "$var"  # varが未設定の場合エラー

ユースケース

予期しない動作のシェルスクリプトのデバッグ、エッジケースを処理する堅牢な自動化の作成、チームスクリプトでの変数初期化の強制。環境変数に依存するスクリプトで特に重要です。

試してみる — Shell Script Linter

フルツールを開く