SC2012: シェルスクリプトでlsの出力を解析しない

lsの出力の解析が信頼できない理由。find、グロブパターン、statを使った安全なファイル列挙をbashスクリプトで行う方法を解説します。

Anti-Patterns

詳細な説明

lsを解析してはいけない理由

lsの出力は人間向けであり、スクリプト向けではありません。スペース、改行、特殊文字を含むファイル名で信頼できず、そのフォーマットはシステム間で異なります。

問題

# 悪い例: スペースを含むファイル名で壊れる
for file in $(ls /path/to/dir); do
  process "$file"
done

# ファイル名 "my file.txt" が2回のイテレーションに: "my" と "file.txt"

安全な代替方法

グロブパターン(最もシンプル):

for file in /path/to/dir/*; do
  [ -e "$file" ] || continue  # 空のディレクトリをハンドル
  process "$file"
done

findコマンド(再帰的、条件付き):

# 安全のためにnull終端
find /path -name "*.log" -print0 | while IFS= read -r -d '' file; do
  process "$file"
done

# または-execを使用
find /path -name "*.log" -exec process {} \;

ファイル情報にはstat:

# ls -lのファイルサイズ解析の代わり:
size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null)

一般的なls解析の間違い

悪いパターン 安全な代替
`ls *.txt wc -l`
`ls -t head -1`
`ls -la grep "^d"`
for f in $(ls) for f in *

ユースケース

ファイルのリスト、イテレーション、カウントが必要なすべてのスクリプト。バックアップスクリプト、ログローテーション、ファイル管理自動化、ディレクトリ内のファイルを処理するデプロイスクリプト。

試してみる — Shell Script Linter

フルツールを開く