前回紹介したように、lsofコマンドでは、開かれているファイルと、それを開いているプロセスの情報を簡単に取得することができる。基本的には、次のように何も引数を指定しないで実行すれば、欲しい情報を得られるようになっている。

% lsof
COMMAND    PID   USER   FD     TYPE             DEVICE           SIZE/OFF    NODE NAME
kernel       0   root  cwd     VDIR               0,90                512       2 /
kernel       0   root  rtd     VDIR               0,90                512       2 /
init         1   root  cwd     VDIR               0,90                512       2 /
init         1   root  rtd     VDIR               0,90                512       2 /
init         1   root  txt     VREG               0,90            1061880 2809013 /sbin/init
adjkerntz  148   root  cwd     VDIR               0,90                512       2 /
adjkerntz  148   root  rtd     VDIR               0,90                512       2 /
adjkerntz  148   root  txt     VREG               0,90               9896 2808973 /sbin/adjkerntz
adjkerntz  148   root  txt     VREG               0,90             136760 3290906 /libexec/ld-elf.so.1
adjkerntz  148   root  txt     VREG               0,90            1744432  240771 /lib/libc.so.7
adjkerntz  148   root    0u    VCHR               0,26                0t0      26 /dev/null
adjkerntz  148   root    1u    VCHR               0,26                0t0      26 /dev/null
adjkerntz  148   root    2u    VCHR               0,26                0t0      26 /dev/null
...略...
lsof      6210 daichi  cwd     VDIR               0,90               1024  481537 /Users/daichi
lsof      6210 daichi  rtd     VDIR               0,90                512       2 /
lsof      6210 daichi  txt     VREG               0,90             133728 2086789 /usr/local/sbin/lsof
lsof      6210 daichi  txt     VREG               0,90             136760 3290906 /libexec/ld-elf.so.1
lsof      6210 daichi  txt     VREG               0,90              60552  240805 /lib/libkvm.so.7
lsof      6210 daichi  txt     VREG               0,90            1744432  240771 /lib/libc.so.7
lsof      6210 daichi  txt     VREG               0,90              97592  240798 /lib/libelf.so.2
lsof      6210 daichi    0u    VCHR              0,106           0t329561     106 /dev/pts/0
lsof      6210 daichi    1u    VCHR              0,106           0t329561     106 /dev/pts/0
lsof      6210 daichi    2u    VCHR              0,106           0t329561     106 /dev/pts/0
lsof      6210 daichi    3r    VCHR               0,19                0t0      19 /dev/mem
lsof      6210 daichi    4r    VCHR               0,20 0xfffff8001a2e8550      20 /dev/kmem
%

左端の列にプロセス名(コマンド名)、右端の列に開かれているファイルのパスが表示される。

「これでは出力されるものが多すぎて見づらい」というようであれば、awkコマンドを使って必要なものだけを出力させるようにすればよいだろう。

覚えておきたいlsofコマンドの使い方

lsofコマンドでまず覚えておきたいのは、次のように引数にファイルパスを指定する方法だ。

% lsof /dev/null
COMMAND    PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
adjkerntz  148   root    0u  VCHR   0,26      0t0   26 /dev/null
adjkerntz  148   root    1u  VCHR   0,26      0t0   26 /dev/null
adjkerntz  148   root    2u  VCHR   0,26      0t0   26 /dev/null
devd       348   root    0u  VCHR   0,26      0t0   26 /dev/null
devd       348   root    1u  VCHR   0,26      0t0   26 /dev/null
devd       348   root    2u  VCHR   0,26      0t0   26 /dev/null
syslogd    492   root    0u  VCHR   0,26      0t0   26 /dev/null
syslogd    492   root    1u  VCHR   0,26      0t0   26 /dev/null
syslogd    492   root    2u  VCHR   0,26      0t0   26 /dev/null
rpcbind    511   root    0u  VCHR   0,26      0t0   26 /dev/null
rpcbind    511   root    1u  VCHR   0,26      0t0   26 /dev/null
rpcbind    511   root    2u  VCHR   0,26      0t0   26 /dev/null
rpc.statd  545   root    0u  VCHR   0,26      0t0   26 /dev/null
rpc.statd  545   root    1u  VCHR   0,26      0t0   26 /dev/null
rpc.statd  545   root    2u  VCHR   0,26      0t0   26 /dev/null
rpc.lockd  548   root    0u  VCHR   0,26      0t0   26 /dev/null
rpc.lockd  548   root    1u  VCHR   0,26      0t0   26 /dev/null
rpc.lockd  548   root    2u  VCHR   0,26      0t0   26 /dev/null
nginx      600   root    0u  VCHR   0,26      0t0   26 /dev/null
nginx      600   root    1u  VCHR   0,26      0t0   26 /dev/null
nginx      602 daichi    0u  VCHR   0,26      0t0   26 /dev/null
nginx      602 daichi    1u  VCHR   0,26      0t0   26 /dev/null
sshd       637   root    0u  VCHR   0,26      0t0   26 /dev/null
sshd       637   root    1u  VCHR   0,26      0t0   26 /dev/null
sshd       637   root    2u  VCHR   0,26      0t0   26 /dev/null
sendmail   640   root    0r  VCHR   0,26      0t0   26 /dev/null
sendmail   640   root    1w  VCHR   0,26      0t0   26 /dev/null
sendmail   640   root    2w  VCHR   0,26      0t0   26 /dev/null
sendmail   643  smmsp    0r  VCHR   0,26      0t0   26 /dev/null
sendmail   643  smmsp    1w  VCHR   0,26      0t0   26 /dev/null
sendmail   643  smmsp    2w  VCHR   0,26      0t0   26 /dev/null
cron       647   root    0u  VCHR   0,26      0t0   26 /dev/null
cron       647   root    1u  VCHR   0,26      0t0   26 /dev/null
cron       647   root    2u  VCHR   0,26      0t0   26 /dev/null
autounmou  694   root    0u  VCHR   0,26      0t0   26 /dev/null
autounmou  694   root    1u  VCHR   0,26      0t0   26 /dev/null
autounmou  694   root    2u  VCHR   0,26      0t0   26 /dev/null
automount  699   root    0u  VCHR   0,26      0t0   26 /dev/null
automount  699   root    1u  VCHR   0,26      0t0   26 /dev/null
automount  699   root    2u  VCHR   0,26      0t0   26 /dev/null
sshd       716   root    0r  VCHR   0,26      0t0   26 /dev/null
sshd       716   root    1u  VCHR   0,26      0t0   26 /dev/null
sshd       716   root    2u  VCHR   0,26      0t0   26 /dev/null
sshd       718 daichi    0u  VCHR   0,26      0t0   26 /dev/null
sshd       718 daichi    1u  VCHR   0,26      0t0   26 /dev/null
sshd       718 daichi    2u  VCHR   0,26      0t0   26 /dev/null
ssh-agent  801 daichi    0u  VCHR   0,26      0t0   26 /dev/null
ssh-agent  801 daichi    1u  VCHR   0,26      0t0   26 /dev/null
ssh-agent  801 daichi    2u  VCHR   0,26      0t0   26 /dev/null
sh        5407 daichi    0r  VCHR   0,26      0t0   26 /dev/null
sh        5407 daichi    1w  VCHR   0,26      0t0   26 /dev/null
sh        5407 daichi    2w  VCHR   0,26      0t0   26 /dev/null
nvim      5414 daichi   15r  VCHR   0,26      0t0   26 /dev/null
nvim      5414 daichi   22r  VCHR   0,26      0t0   26 /dev/null
nvim      5414 daichi   29r  VCHR   0,26      0t0   26 /dev/null
ydwait    6273 daichi    0r  VCHR   0,26      0t0   26 /dev/null
ydwait    6273 daichi    1w  VCHR   0,26      0t0   26 /dev/null
ydwait    6273 daichi    2w  VCHR   0,26      0t0   26 /dev/null
nvim      6274 daichi   15r  VCHR   0,26      0t0   26 /dev/null
nvim      6274 daichi   22r  VCHR   0,26      0t0   26 /dev/null
nvim      6274 daichi   29r  VCHR   0,26      0t0   26 /dev/null
%

このようにlsofコマンドを実行した場合、指定したファイルパスにあるファイルを開いているプロセスのみを表示させることができる。調べたいファイルが明らかな場合には、lsofコマンドの引数にそのファイルのパスを指定してコマンドを実装すればよいわけだ。

もう1つ覚えておきたいのが、「+D」というオプションだ。このオプションには、さらに引数としてディレクトリを指定する。すると、指定したディレクトリ以下のファイルを開いているプロセスの一覧を得ることができる。

例えば、ログファイルを保持するために使われることが多い/var/log/ディレクトリを+Dの引数として指定すれば,次のように/var/log/の下にログデータを出力しているプロセスの情報を得ることができる。

% lsof +D /var/log/
COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
syslogd  492   root   11w  VREG   0,90    98261  884197 /var/log/messages
syslogd  492   root   12w  VREG   0,90       59  883315 /var/log/security
syslogd  492   root   13w  VREG   0,90    88974  883184 /var/log/auth.log
syslogd  492   root   14w  VREG   0,90     1731  885649 /var/log/maillog
syslogd  492   root   15w  VREG   0,90       59  883310 /var/log/lpd-errs
syslogd  492   root   16w  VREG   0,90       59  883316 /var/log/xferlog
syslogd  492   root   17w  VREG   0,90    60101  885116 /var/log/cron
syslogd  492   root   18w  VREG   0,90      318  883309 /var/log/debug.log
syslogd  492   root   19w  VREG   0,90       59  883313 /var/log/ppp.log
nginx    600   root    2w  VREG   0,90   112966 2167621 /var/log/nginx/error.log
nginx    600   root    4w  VREG   0,90  3545140 2167622 /var/log/nginx/access.log
nginx    600   root    5w  VREG   0,90   112966 2167621 /var/log/nginx/error.log
nginx    602 daichi    2w  VREG   0,90   112966 2167621 /var/log/nginx/error.log
nginx    602 daichi    4w  VREG   0,90  3545140 2167622 /var/log/nginx/access.log
nginx    602 daichi    5w  VREG   0,90   112966 2167621 /var/log/nginx/error.log
%

つまり、どのプロセスがどのファイルにログデータを出力しているのかを調べることができるというわけだ。

lsofコマンドにはさまざまなオプションが用意されているが、基本的にはこの辺りの操作を知っておくだけで、かなり便利に使うことができる。また、lsofコマンドに限らないが、sortコマンドやawkコマンドを使って出力内容を整理できると一層効率が上がる。それらのコマンドの使い方については、既に本連載で取り上げているので、そちらで復習していただきたい。