findとxargsで古いログを一括gzip、ファイル名にスペースがあると壊れる

  • Shell
  • find
  • xargs
  • Linux

この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。

何をしたか

15日以上前の .log ファイルをまとめて gzip する処理を書いた。

find /path/to/logs -name "*.log" -mtime +15 -type f | xargs gzip

-mtime +15 で更新日時が15日より前のものに絞り、-type f で通常ファイルのみに限定してから xargs 経由で gzip に渡す。既に .gz になったファイルは *.log にマッチしないので、再実行しても二重圧縮にはならない。

問題点

find | xargs の組み合わせは、find の出力を改行区切りのテキストとして扱う。ファイル名自体にスペースや改行が含まれていると、xargs 側で意図しない分割が起きて、存在しないパスとして渡ってしまうことがある。

ログファイル名が日付や英数字だけで構成されている運用なら実害はないが、汎用的なスクリプトとして使い回すには安全とは言えない。

対処

find -print0 と xargs -0 を組み合わせると、区切り文字がNUL文字になる。NUL文字はファイル名に使えない文字なので、スペースや改行を含むファイル名でも壊れない。

find /path/to/logs -name "*.log" -mtime +15 -type f -print0 | xargs -0 gzip

結論

ファイル名の命名規則が保証されている環境(日付・英数字のみなど)であれば元のコマンドのままで問題は起きない。ただし汎用的に使うスクリプトとして書くなら、-print0 / -0 を付けておいた方が安全。