「ポートが使用中と言われるが、どのプロセスが使っているのか見当がつかない」
サーバー運用をしていると、こういった場面に必ず遭遇します。再起動しても解決しない、ログを見ても手がかりがない——そんな時に頼りになるのが lsof コマンドです。
この記事では、lsof コマンドの基本的な使い方から、ポート調査・プロセス特定・障害切り分けまでの実践的な活用法を解説します。RHEL 9.4 / Rocky Linux 9.4 / Ubuntu 24.04 LTS で動作確認済みです。
この記事のポイント
・lsof は「List Open Files」の略でプロセスが開くすべてのリソースを一覧できる
・lsof -i :80 で特定ポートを使っているプロセスを即座に特定できる
・lsof -p PID でプロセスが開いているファイル・ソケットを一括確認できる
・削除済みファイルを掴み続けるプロセスもlsofで発見・解放できる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
lsof とは何か?なぜ現場で欠かせないのか
lsof は「List Open Files」の略で、その名のとおり「開かれているファイルの一覧を表示する」コマンドです。ただし Linux においては「ファイル」の概念が非常に広く、通常のテキストファイルや実行ファイルだけでなく、ディレクトリ・シンボリックリンク・デバイスファイル・パイプ・ソケット(TCP/UDP接続)・共有ライブラリ(.so ファイル)もすべて「ファイル」として扱われます。
つまり lsof を使えば、あるプロセスが現在どのネットワーク接続を持っているか、どのログファイルを開いているか、どのライブラリを読み込んでいるかを一度に把握できるわけです。
・ポートが競合している原因を特定する
・削除したはずのログファイルがディスクを圧迫し続けている原因を探す
・プロセスが特定のファイルを掴んで離さないためアンマウントできない問題を解決する
・不審なプロセスの外部通信先を調査する
これらすべてが lsof 一本で対処できます。20年以上サーバーを運用してきた経験から言うと、lsof は netstat の廃止後に特に重要性が増したコマンドです。現場でまだ使いこなせていない方は、この機会にぜひ習得してください。
lsof のインストールと基本構文
1. インストール確認とインストール方法
多くのディストリビューションには lsof がプリインストールされています。まず確認しましょう。# バージョン確認 $ lsof --version revision: 4.98.0 latest revision: https://github.com/nicowillis/lsof
# RHEL / Rocky Linux / AlmaLinux $ sudo dnf install -y lsof # Ubuntu / Debian $ sudo apt install -y lsof
2. 基本構文
lsof [オプション] [ファイル名/ディレクトリ名]
# 全プロセスのオープンファイル一覧(root権限推奨) $ sudo lsof | head -5 COMMAND PID TID TASKCMD USER FD TYPE DEVICE SIZE/OFF NODE NAME systemd 1 root cwd DIR 253,1 4096 2 / systemd 1 root rtd DIR 253,1 4096 2 / systemd 1 root txt REG 253,1 1628592 525575 /usr/lib/systemd/systemd systemd 1 root mem REG 253,1 228168 1311879 /usr/lib64/ld-linux-x86-64.so.2
| カラム名 | 意味 |
|---|---|
| COMMAND | プロセス名(コマンド名) |
| PID | プロセスID |
| USER | プロセスを実行しているユーザー |
| FD | ファイルディスクリプタの種別(cwd=カレントディレクトリ、txt=実行ファイル、mem=メモリマップ、数字=ファイルディスクリプタ番号) |
| TYPE | ファイルの種類(REG=通常ファイル、DIR=ディレクトリ、IPv4/IPv6=ソケット) |
| DEVICE | デバイス番号(メジャー:マイナー) |
| SIZE/OFF | ファイルサイズまたはオフセット |
| NODE | iノード番号またはプロトコル |
| NAME | ファイルパス、ソケットのアドレス:ポートなど |
ネットワーク・ポート調査の実践
1. 特定ポートを使用しているプロセスを特定する
最もよく使うパターンです。ポート番号を指定して絞り込みます。# ポート80を使用しているプロセスを確認 $ sudo lsof -i :80 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME httpd 1423 root 4u IPv6 24518 0t0 TCP *:http (LISTEN) httpd 1424 apache 4u IPv6 24518 0t0 TCP *:http (LISTEN) httpd 1425 apache 4u IPv6 24518 0t0 TCP *:http (LISTEN)
# ポート22(SSH)を確認 $ sudo lsof -i :22 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 1187 root 3u IPv4 21942 0t0 TCP *:ssh (LISTEN) sshd 1187 root 4u IPv6 21944 0t0 TCP *:ssh (LISTEN) sshd 14521 root 10u IPv4 437628 0t0 TCP sv01.example.internal:ssh->10.10.1.55:52341 (ESTABLISHED)
2. プロトコルを指定して絞り込む
# TCPのみ表示 $ sudo lsof -i tcp # UDPのみ表示 $ sudo lsof -i udp # TCP接続中(ESTABLISHED)のみ表示 $ sudo lsof -i tcp -s TCP:ESTABLISHED # LISTEN状態のみ表示 $ sudo lsof -i tcp -s TCP:LISTEN
3. すべてのネットワーク接続を一覧表示する
# 全ネットワーク接続(TCP+UDP) $ sudo lsof -i COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME chronyd 886 chrony 5u IPv4 19873 0t0 UDP localhost:323 sshd 1187 root 3u IPv4 21942 0t0 TCP *:ssh (LISTEN) sshd 1187 root 4u IPv6 21944 0t0 TCP *:ssh (LISTEN) httpd 1423 root 4u IPv6 24518 0t0 TCP *:http (LISTEN) httpd 1423 root 6u IPv6 24520 0t0 TCP *:https (LISTEN)
プロセス別のファイル調査
1. 特定プロセスが開いているファイルを確認する(PID指定)
# PIDを指定して確認 $ sudo lsof -p 1423 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME httpd 1423 root cwd DIR 253,1 4096 2 / httpd 1423 root txt REG 253,1 541560 537281 /usr/sbin/httpd httpd 1423 root mem REG 253,1 68776 1311879 /usr/lib64/libpthread.so.0 httpd 1423 root 4u IPv6 24518 0t0 TCP *:http (LISTEN) httpd 1423 root 6u IPv6 24520 0t0 TCP *:https (LISTEN) httpd 1423 root 7u REG 253,1 0 531244 /run/httpd/httpd.pid httpd 1423 root 8w REG 253,1 1048576 526891 /var/log/httpd/access_log httpd 1423 root 9w REG 253,1 16384 526892 /var/log/httpd/error_log
2. コマンド名でプロセスを絞り込む
PIDが分からなくてもコマンド名で指定できます。# コマンド名で絞り込む(-c オプション) $ sudo lsof -c httpd # コマンド名は前方一致。例えば python で始まる全プロセスが対象 $ sudo lsof -c python
3. 特定ユーザーが開いているファイルを確認する
# ユーザー指定(-u オプション) $ sudo lsof -u tomohiro # 特定ユーザー以外を表示(^ で否定) $ sudo lsof -u ^root
ファイル・ディレクトリを指定した調査
1. 特定ファイルを開いているプロセスを確認する
ファイルを削除できない、アンマウントできない場面で特に役立ちます。# /var/log/httpd/access_log を開いているプロセスを確認 $ sudo lsof /var/log/httpd/access_log COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME httpd 1423 root 8w REG 253,1 1048576 526891 /var/log/httpd/access_log httpd 1424 apache 8w REG 253,1 1048576 526891 /var/log/httpd/access_log
2. 特定ディレクトリ配下を開いているプロセスを確認する(+D オプション)
# /var/log/httpd/ ディレクトリ配下すべてを対象に $ sudo lsof +D /var/log/httpd/ COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME httpd 1423 root 8w REG 253,1 1048576 526891 /var/log/httpd/access_log httpd 1423 root 9w REG 253,1 16384 526892 /var/log/httpd/error_log httpd 1424 apache 8w REG 253,1 1048576 526891 /var/log/httpd/access_log
3. マウントポイントを使用しているプロセスを確認する
アンマウント時に「device is busy」が出た場合の定番調査手順です。# /mnt/data をアンマウントしようとしたら device is busy と言われた場合 $ sudo umount /mnt/data umount: /mnt/data: target is busy. # どのプロセスが /mnt/data を使用しているか確認 $ sudo lsof +D /mnt/data COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 2034 tomohiro cwd DIR 253,2 4096 2 /mnt/data rsync 4521 root cwd DIR 253,2 4096 2 /mnt/data # PID 2034 と 4521 を終了させてからアンマウント $ sudo kill 2034 4521 $ sudo umount /mnt/data
削除済みファイルを掴み続けるプロセスの対処
1. deleted ファイルの発見
ログローテーションや手動削除後に、プロセスが古いファイルディスクリプタを保持し続けることがあります。ファイルはディスク上に残り続け、空き容量を圧迫します。# deleted 状態のファイルを確認 $ sudo lsof | grep deleted httpd 1423 root 8w REG 253,1 2147483648 526891 /var/log/httpd/access_log (deleted) java 3105 tomcat 52w REG 253,1 5368709120 512044 /opt/tomcat/logs/catalina.out (deleted)
2. 対処方法
最も安全な方法はプロセスを再起動することです。ただし再起動できない場合は、ファイルディスクリプタ経由でファイルを空にする方法もあります。# httpd プロセス(PID=1423)のFD番号8のファイルを空にする # /proc/PID/fd/FD_NUMBER にアクセスしてtruncateする $ sudo truncate -s 0 /proc/1423/fd/8 # または > でリダイレクト(ファイルを空にする) $ sudo sh -c '> /proc/1423/fd/8'
複数オプションを組み合わせた実務パターン
1. 特定ユーザーのネットワーク接続を確認する
# www-data ユーザーのネットワーク接続一覧 $ sudo lsof -u www-data -i
2. 複数のPIDを同時に指定する
# 複数のPIDを指定(カンマ区切りでも可) $ sudo lsof -p 1423,1424,1425
3. AND 条件で絞り込む(-a オプション)
デフォルトでは複数のオプションは OR 条件になります。AND 条件にするには `-a` を使います。# httpd プロセスのネットワーク接続のみ表示(-a でAND条件) $ sudo lsof -c httpd -a -i # tomohiro ユーザーが /var/log/ 配下を開いているファイルのみ $ sudo lsof -u tomohiro -a +D /var/log/
4. 定期的にリピートして監視する(-r オプション)
# 5秒ごとにポート443の状態を繰り返し表示 $ sudo lsof -i :443 -r 5
5. lsof の出力をパイプで加工する
# ネットワーク接続をソートして件数確認 $ sudo lsof -i | awk '{print $1}' | sort | uniq -c | sort -rn | head -10 # 結果例: # 18 httpd # 6 sshd # 2 chronyd # 1 COMMAND
トラブルシュート:よくあるエラーと対処法
「Permission denied」や出力が空になる場合
lsof は自分が実行できるプロセスの情報しか取得できません。他ユーザーのプロセスや root 所有のプロセスを調査するには sudo が必要です。# 一般ユーザーで実行すると権限のないプロセスは出力されない $ lsof -i :80 # (空または自分のプロセスのみ) # sudo を付けると全プロセスが対象になる $ sudo lsof -i :80 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME httpd 1423 root 4u IPv6 24518 0t0 TCP *:http (LISTEN)
「lsof: WARNING: can't stat() ... File system ... has been skipped」が出る場合
NFSやループバックデバイスなど、アクセスできないファイルシステムがある場合に表示される警告です。調査対象に影響がなければ無視して構いません。`-w` オプションで警告を抑制できます。# 警告を抑制して実行 $ sudo lsof -w -i :80
lsof の出力が多すぎて見にくい場合
# grep で絞り込む $ sudo lsof -i | grep ESTABLISHED # FD 列でファイルディスクリプタのみに絞る(数字始まりのFDのみ) $ sudo lsof -p 1423 | grep -E '^\S+\s+\d+.*[0-9]+[rw]?\s'
lsof と ss・netstat の使い分け
ネットワーク調査では lsof 以外に ss コマンドも使われます。用途に応じて使い分けましょう。| コマンド | 主な用途 | 強み |
|---|---|---|
lsof -i |
ポートとプロセスを紐づけて確認 | プロセス名・ユーザー・ファイルが一度に確認できる |
ss -tlnp |
LISTEN中のポートを高速に確認 | 出力が速い・タイマー情報も確認できる |
lsof +D /path |
ファイル・ディレクトリを使用中のプロセス特定 | ネットワーク以外のファイルにも対応 |
lsof | grep deleted |
削除済みファイルの確認 | lsof 独自の機能 |
詳しいポート確認方法については「Linux ポート確認の全コマンド」も合わせてご覧ください。
本記事のまとめ
lsof コマンドの主要な使い方をまとめます。| やりたいこと | コマンド |
|---|---|
| 特定ポートを使うプロセスを特定 | sudo lsof -i :ポート番号 |
| TCP接続中のセッションを確認 | sudo lsof -i tcp -s TCP:ESTABLISHED |
| LISTEN中のポートをすべて確認 | sudo lsof -i tcp -s TCP:LISTEN |
| PID指定でプロセスのファイルを確認 | sudo lsof -p PID番号 |
| コマンド名でプロセスを絞り込み | sudo lsof -c コマンド名 |
| 特定ファイルを開くプロセスを確認 | sudo lsof /path/to/file |
| ディレクトリ配下を使うプロセスを確認 | sudo lsof +D /path/to/dir |
| 削除済みファイルを掴むプロセスを検索 | sudo lsof | grep deleted |
| 複数オプションをAND条件で絞り込み | sudo lsof -c コマンド名 -a -i |
| 定期的にリピートして監視 | sudo lsof -i :ポート番号 -r 秒数 |
lsof が真価を発揮するのは、「なぜこのプロセスが重いのか」「なぜディスクが減っているのか」「なぜアンマウントできないのか」といった、原因不明のトラブルに直面した時です。netstat が廃止された現在、lsof と ss の両方を使いこなせることが現場エンジニアの標準スキルになっています。
関連記事もあわせて確認してください。
・Linux ポート確認の全コマンド
・systemd-analyze で起動時間計測
・Linux DNS 設定の基本
lsof は知っているのに、障害対応の場面で即座に使えていませんか?
コマンドの構文を覚えるだけでは現場では通用しません。「どのタイミングで何を確認するか」というトラブルシュートの型を持つことが重要です。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら
- 次のページへ:lddコマンドで共有ライブラリの依存関係を確認する方法|not foundエラーの解決とldconfigの活用も
- 前のページへ:loggerコマンドでシステムログに任意のメッセージを記録する方法|rsyslog転送やシェルスクリプト活用も
- この記事の属するカテゴリ:Linuxtipsへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます