SC2155: 終了コードを保持するためにlocalの宣言と代入を分離

local変数の宣言と代入を分離してコマンド失敗のマスキングを回避。信頼性の高いエラー検出のためにSC2155を修正します。

Error Handling

詳細な説明

local var=$(command)の隠れたバグ

local(またはexportdeclare)をコマンド置換と組み合わせると、コマンドの終了ステータスがlocalキーワードの終了ステータスに置き換えられます。これはほぼ常に0(成功)です。

問題

my_function() {
  local result=$(failing_command)  # 終了コードがマスクされる
  echo "Result: $result"           # コマンドが失敗しても実行される!
}

set -eを使用していても、localが0を返すためスクリプトは終了しません:

set -e
my_function() {
  local output=$(false)  # falseは1を返すが、localは0を返す
  echo "これは実行される!"  # まだ実行される
}
my_function

修正方法

宣言と代入を別の行にします:

my_function() {
  local result
  result=$(failing_command)  # 終了コードが保持される
  echo "Result: $result"     # 成功時のみ実行(set -eの場合)
}

exportとdeclareでも同じ問題

# 悪い例: 終了コードがマスクされる
export PATH=$(build_path)
declare -r CONFIG=$(load_config)

# 良い例: 宣言と代入を分離
export PATH
PATH=$(build_path)

declare -r CONFIG
CONFIG=$(load_config)

ベストプラクティス

関数内では常に宣言と代入を分離してください。コストはかからず、失敗がサイレントに無視されるデバッグ困難な問題のクラスを防ぎます。

ユースケース

外部コマンドを呼び出し、信頼性の高いエラー検出が必要なBash関数。ライブラリスクリプト、エラーハンドリングラッパー、コマンドの戻り値が制御フローを決定するすべての関数で一般的です。

試してみる — Shell Script Linter

フルツールを開く