一時ファイルが溜まり続け、`/tmp` が圧迫されていた。瀬名はcronで消そうとしたが、律は使用中ファイルを確認した。
`lsof +D /tmp`
古いプロセスが削除済みファイルを掴んだまま、容量を返していなかった。`du` と `df` の差分もそれを示している。
二人はプロセスを安全に再起動し、systemd-tmpfilesの設定を見直した。
「消したのに残るって、怖いですね」
律が言った。
「未練みたいです」
瀬名が何気なく返すと、律は一瞬だけ手を止めた。
「瀬名さん、たまに雑に刺しますね」
その声に怒りはなかった。少しだけ、痛そうだった。
人物紹介
瀬名悠真
- 男性、30代
- サーバ運用・インフラ担当
- 手は動くが、初動で少し焦りやすい
久坂律
- 女性、30代
- 監視、自動化、ログ解析、運用設計に強い
- 冷静で、原因調査の順序を大事にする
用語メモ
lsof +D /tmp
lsof +D /tmp は、Linux/UNIX系システムで 「/tmp ディレクトリ配下にあるファイルを開いているプロセスを再帰的に検索・一覧表示するコマンド」 です。
コマンドの構成と各要素の意味について詳しく解説します!
🔍 コマンドの分解解説
-
lsof(LiSt Open Files) システム上で「現在どのプロセスがどのファイル(またはディレクトリやソケット)を開いているか」を確認するためのコマンドです。 -
+D(再帰的検索オプション) 指定したディレクトリとそのサブディレクトリ配下まですべて再帰的に辿って、開かれているファイルを検索します。 (※ 似たオプションに-Dや+dがありますが、+dは指定したディレクトリの直下のみを検索し、サブディレクトリまで潜りません) -
/tmp検索対象となるディレクトリです。一時ファイルが置かれるため、削除できないファイルやプロセスを特定したい時によく指定されます。
📊 出力結果の見方(例)
コマンドを実行すると、以下のような形式で結果が表示されます。
Plaintext
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 1234 root 3u REG 8,1 1024 524288 /tmp/nginx.lock
python3 5678 user1 4r REG 8,1 4096 524289 /tmp/work/data.csv
主な項目の意味:
-
COMMAND : ファイルを開いているプロセス名(例: nginx, python3)
-
PID : プロセスID(プロセスを終了させたい時に使う番号)
-
USER : プロセスを実行しているユーザー名
-
FD : ファイルディスクリプタ(ファイルの開かれ方。
rは読み込み、wは書き込みなど) -
TYPE : ファイルのタイプ(
REGは通常のファイル、DIRはディレクトリ) -
NAME : 実際に開かれているファイルの絶対パス
💡 どういう時に使う?(具体的な利用シーン)
-
/tmp配下のファイルを削除したいのに「使用中」で消せない・ロックされている時 どのプロセスがファイルを掴んでいるか(ロックしているか)を特定できます。 -
アンマウントエラー(
Device or resource is busy)が出た時 特定のマウントポイント(パーティション)内のファイルを使っているプロセスを割り出すのに役立ちます。 -
不要なプロセスや消し忘れの一時ファイルプロセスを特定したい時 バックグラウンドで動き続けて
/tmpの容量を圧迫しているプログラムを見つけることができます。
🛠️ よく使う応用テクニック
① 該当プロセスを一括で強制終了する
特定したプロセスのPID(上記例なら 5678)を確認して kill 5678 とするのも良いですが、lsof の -t オプション(PIDのみ出力)と組み合わせることで一括終了も可能です。
Bash
# /tmp 配下のファイルを使っているプロセスのPIDだけを表示
lsof +tD /tmp
# それらのプロセスを一括で終了(※注意して実行してください)
kill -9 $(lsof +tD /tmp)
② 大文字 +D と 小文字 +d の違い
-
lsof +d /tmp➔/tmp/abc.txtなど直下のみを検索(速い) -
lsof +D /tmp➔/tmp/sub/dir/abc.txtのように深い階層まで検索(やや時間がかかる場合あり)
⚠️ 注意点
/tmp 全体を +D で検索する場合、ファイル数やサブディレクトリ数が非常に多いと、検索完了までに少し時間がかかる(CPU/ディスク負荷が上がる)ことがあります。特定のサブディレクトリが分かっている場合は lsof +D /tmp/my_app/ のように対象を絞り込むのがおすすめです。
systemd-tmpfiles
systemd-tmpfiles は、Linuxシステム(systemdを採用しているOS)において、一時ファイルやディレクトリ、ソケット、シンボリックリンクなどの「作成・削除・クリーンアップ」を自動管理する仕組み(およびそのコマンド) です。
以前は /tmp や /var/tmp のお掃除を cron などで定期実行していましたが、現代の主要なLinuxディストリビューション(Ubuntu, RHEL, Debian, CentOSなど)では、この systemd-tmpfiles がその役割を標準で担っています。
💡 どんな役割をしているの?
主に以下の3つの処理を自動で行ってくれます。
-
起動時の自動作成(Creation)
システム起動時に、アプリの動作に必要なディレクトリ(例:
/run/myapp/や/tmp/lock/など)がなければ、正しい所有者(ユーザー/グループ)やパーミッション(権限)で自動作成します。(※
/runや/tmpはメモリ上(tmpfs)に配置されることが多いため、再起動すると消えてしまいます。それを起動時に再構築する重要な役割です) -
古いファイルの自動削除(Clean / Ageing)
/tmpや/var/tmpなどに放置された古いファイルを、最後にアクセスされてからの経過時間(Age) を元に自動で削除(クリーンアップ)します。 -
空のディレクトリやファイルの安全な削除(Remove)
シャットダウン時や定期実行時に、不要になった特定ファイルや空のディレクトリを安全に削除します。
📂 設定ファイルはどこにある?
設定は .conf ファイルで記述され、以下の3つの場所に配置されます(数字が小さい順に優先度が高くなります)。
| 優先度 | ディレクトリ | 役割・用途 |
| 1 (最優先) | /etc/tmpfiles.d/*.conf |
管理者(ユーザー)が独自に設定を書き加える場所 |
| 2 | /run/tmpfiles.d/*.conf |
パッケージなどが実行時に動的に作成する設定 |
| 3 (標準) | /usr/lib/tmpfiles.d/*.conf |
OSやインストールされたパッケージのデフォルト設定 |
※独自の設定を追加・カスタマイズしたい場合は、/etc/tmpfiles.d/ 配下に .conf ファイルを作成します。
📜 設定ファイルの書き方(構文)
設定ファイルは、1行ごとに以下のようなフォーマットで記述します。
Plaintext
# タイプ パス モード UID GID 保持期間 対象(引数)
d /run/myapp 0755 root root - -
q /var/tmp 1777 root root 30d -
e /tmp 1777 root root 10d -
主な設定項目
-
Type(タイプ): 動作の種別を指定します。
-
d: ディレクトリが存在しなければ作成する。 -
D: ディレクトリを作成し、クリーンアップ時に中身を空にする。 -
e: ディレクトリ自体は作成せず、中身の古くなったファイルだけを削除対象にする(/tmpなどでよく使われます)。 -
f/F: ファイルを作成する。 -
L: シンボリックリンクを作成する。
-
-
Path: 対象のパス(例:
/tmpや/run/myapp)。 -
Mode: パーミッション(例:
0755や1777)。 -
UID / GID: 所有ユーザーおよび所有グループ。
-
Age(保持期間): ファイルが削除されるまでの期間指定。
-
10d(10日)、12h(12時間)、30m(30分)、-(自動削除なし)など。
-
デフォルト例(/tmp と /var/tmp の違い)
一般的なLinuxの標準設定では、以下のように保持期間が分かれていることが多いです。
/tmpの古いファイル ➔ 10日間アクセスがなければ削除
/var/tmpの古いファイル ➔ 30日間アクセスがなければ削除
🛠️ コマンドの実行・操作方法
systemd-tmpfiles コマンドを手動で実行することで、設定ファイルのテストや即時クリーンアップが行えます。
1. 設定に従ってファイル/ディレクトリを作成する(–create)
Bash
sudo systemd-tmpfiles --create
※新しい設定ファイルを追加した際、再起動せずに今すぐディレクトリを作らせたい時に使います。
2. 古いファイルを今すぐ削除(クリーンアップ)する(–clean)
Bash
sudo systemd-tmpfiles --clean
※/tmp 容量が圧迫されている際、手動で安全に期限切れファイルを掃除できます。
3. 指定した削除設定を実行する(–remove)
Bash
sudo systemd-tmpfiles --remove
4. 設定のドライラン(試し実行・テスト)
実際に削除や作成をせず、何が起きるか確認したい場合:
Bash
sudo systemd-tmpfiles --clean --dry-run
⏰ どうやって自動実行されているの?
systemd のタイマー機能(systemd-tmpfiles-clean.timer)によって管理されています。
以下のコマンドで、次回の自動クリーンアップ処理がいつ実行されるかを確認できます。
Bash
systemctl status systemd-tmpfiles-clean.timer
通常は 1日1回、バックグラウンドで自動的に --clean コマンドが呼び出され、期限切れの一時ファイルが綺麗に掃除されています。
📝 まとめ
-
systemd-tmpfiles は、
/tmpや/runなどの「一時ファイル・ディレクトリの作成と自動掃除」を一括管理する仕組み。 -
設定を追加したい場合は
/etc/tmpfiles.d/xxx.confを作成する。 -
ディスク容量の圧迫時に安全に掃除したい時は
sudo systemd-tmpfiles --cleanを実行する。
アプリケーションの開発やインフラ構築で「起動時に特定のパーミッションで作業用フォルダを用意したい」「定期的に出力ログやテンポラリファイルを消したい」という場面で非常に役立ちます!
