SC2086: シェルスクリプトにおけるクォートされていない変数展開

bashでクォートされていない変数がワードスプリッティングとグロビングのバグを引き起こす理由を解説。変数展開を正しくダブルクォートしてSC2086を修正します。

Quoting

詳細な説明

クォートされていない変数が危険な理由

シェルスクリプトで最も一般的な間違いの一つは、ダブルクォートなしで変数を使用することです。変数がクォートされていない場合、シェルはその値に対してワードスプリッティングファイル名グロビング(パス名展開)を実行します。

問題

filename="my report.pdf"
rm $filename
# シェルは次のように解釈: rm my report.pdf
# 2つのファイルを削除: "my" と "report.pdf"

クォートありの場合:

filename="my report.pdf"
rm "$filename"
# シェルは次のように解釈: rm "my report.pdf"
# 正しく1つのファイルを削除

ワードスプリッティング

シェルはクォートされていない変数値を$IFSの文字(デフォルトではスペース、タブ、改行)で分割します。スペースを含むファイル名は複数の引数になります:

path="/home/user/my documents"
cd $path    # エラー: /home/user/my: そのようなファイルやディレクトリはありません
cd "$path"  # 正しく動作

グロビング

グロブ文字(*?[)を含むクォートされていない変数は、カレントディレクトリのファイル名に対して展開されます:

pattern="*.txt"
echo $pattern   # カレントディレクトリの全.txtファイルに展開
echo "$pattern" # リテラルな "*.txt" を出力

クォートしない場合

意図的にスプリッティングを行いたい場合があります:

# 配列的な動作のための意図的なワードスプリッティング
flags="-v -n --color"
grep $flags pattern file  # 各フラグが個別の引数になる

ほとんどの場合、常に変数をダブルクォートしてください。shellcheckルールSC2086をガイドとして使用してください。

ユースケース

ファイル名、ユーザー入力、または予期しないコンテンツを含む可能性のある変数を扱うすべてのシェルスクリプトで適切なクォートが必要です。信頼できないソースからのファイルを処理するスクリプト、バックアップスクリプト、デプロイ自動化で特に重要です。

試してみる — Shell Script Linter

フルツールを開く