lsofを使ってどのプロセスがどのファイルを使用中かを確認する


lsofコマンドを利用することでどのプロセスがどのリソースを利用中かを確認できる.普通のHuman Friendlyな表示の他にMachine Friendlyな出力も用意されているので,プログラムから利用することもできる.たとえば,OS Xのディスクをアンマウントするときにどのプロセスが利用しているのかを教えてくれる機能もlsofを利用している.

とりあえずlsofする

プロセス名とユーザー名,利用しているファイルの名前が出てくる.sudoを付けないとすべてのユーザー情報は出せない

COMMAND     PID USER   FD     TYPE             DEVICE   SIZE/OFF     NODE NAME
loginwind    96 hoge  cwd      DIR                1,4       1292        2 /
loginwind    96 hoge  txt      REG                1,4     840176 58008654 /System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow
loginwind    96 hoge  txt      REG                1,4     137152 41410698 /System/Library/LoginPlugins/DisplayServices.loginPlugin/Contents/MacOS/DisplayServices
loginwind    96 hoge  txt      REG                1,4     109920 41410342 /System/Library/LoginPlugins/FSDisconnect.loginPlugin/Contents/MacOS/FSDisconnect
loginwind    96 hoge  txt      REG                1,4       1623 41306596 /System/Library/PrivateFrameworks/LoginUIKit.framework/Versions/A/Resources/keyboard.pdf

プロセスIDから使用中のファイルを検索する

プロセスIDを指定するには-pオプションを使う.以下はDropboxの使用状況を表示した例.

lsof -p 23956X
COMMAND   PID USER   FD     TYPE             DEVICE  SIZE/OFF     NODE NAME
Dropbox 23956X hoge  cwd      DIR                1,4      2822 67933240 /Applications/Dropbox.app/Contents/Resources
Dropbox 23956X hoge  txt      REG                1,4     54016 67933156 /Applications/Dropbox.app/Contents/MacOS/Dropbox
..中略...
Dropbox 23956X hoge   25u    IPv4 0x8950914xxxxxxxxx       0t0      TCP 192.168.x.x:53xxx->server-xxxx.r.cloudfront.net:https (CLOSE_WAIT)
Dropbox 23956X hoge   26u    IPv4 0x8950914xxxxxxxxx       0t0      TCP 192.168.x.x:58xxx->server-xxxx.r.cloudfront.net:https (CLOSE_WAIT)
Dropbox 23956X hoge   27u    IPv4 0x8950914xxxxxxxxx       0t0      TCP *:17500 (LISTEN)

後半のようにファイルの使用状況だけでなくネットワークの接続状況も表示できる.

ファイル名から使用中のプロセスを検索する

lsofの引数としてファイル名を渡すと,そのファイルを使用中のプロセスを一覧表示してくれる.

$ lsof /dev/null
COMMAND     PID USER   FD   TYPE DEVICE   SIZE/OFF NODE NAME
loginwind    96 hoge    0r   CHR    3,2        0t0  304 /dev/null
loginwind    96 hoge    1u   CHR    3,2        0t0  304 /dev/null
loginwind    96 hoge    2u   CHR    3,2    0t22563  304 /dev/null

ネットワークの接続状況だけを表示する

-iオプションと組み合わせることでネットワークの接続状況を表示できる.書式は

-i[46][protocol][@hostname|hostaddr][:service|port]

の通り.もし,TCP/443で接続しているものだけを表示したければ

$ lsof -itcp:https
COMMAND     PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
Twitter     234X hoge   31u  IPv4 0x8950914fffffffff      0t0  TCP 192.168.x.xx:50xxx->xxx.twttr.com:https (ESTABLISHED)
Twitter     234X hoge   32u  IPv4 0x8950914fffffffff      0t0  TCP 192.168.x.xx:50xxx->xxx.twttr.com:https (ESTABLISHED)

のようにする.もし,443をhttpsのようにポート番号を自動的にサービス名に変換されたくなければ-Pをつけると変換されなくなる.ホスト名を逆引したくなければ-nをつける.

自分のホストでLISTEN状態にあるTCP/IPのポート一覧するには-sTCP:LISTENをつける.どのプロセスがポーと利用中か分からないときにはこのコマンドで調べられる.

lsof -itcp -sTCP:LISTEN -P
COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
Python  62187 hoge    3u  IPv4 0x89509149xxxxxxxx      0t0  TCP *:8000 (LISTEN)
Dropbox 23956X hoge   27u  IPv4 0x89509149xxxxxxxx      0t0  TCP *:17500 (LISTEN)
Dropbox 23956X hoge   45u  IPv4 0x89509149xxxxxxxx      0t0  TCP localhost:17600 (LISTEN)
Dropbox 23956X hoge   50u  IPv4 0x89509149xxxxxxxx      0t0  TCP localhost:17603 (LISTEN)

他のプログラムと組み合わせる

-Fオプションで出力を調整できる.たとえば-FcnでプロセスID,プロセス名,ファイル名をMachine Friendlyなフォーマットで出力できる.