たまーに、指定したファイルを使用しているプロセスを調べたいということがある。 そういうとき、大体は lsof や fuser で対象のプロセスを調べるのだけど、そういったツールが入ってない+インストールができない、めんどくさいといった場合、どうやって調べればいいのだろう。

Linux(というか、UNIX系OS共通だと思う)の場合、/proc配下にあるプロセスIDのフォルダの中にある各種ファイルやフォルダに使用しているファイルへのシンボリックリンクが貼られている(fdだったらstdoutやstderrといったファイルディスクリプタに。例として、「cmd > /path/to/xxx」と実行しているプロセスの場合なら、/proc/<pid>/fd/nは/path/to/xxxへのシンボリックリンクになっている)ので、fd,cwdフォルダ配下を調べてやればいい。

でその調べ方なのだけど、以下のようにlsやfindで/proc配下を出力して、grepで対象のファイルPATHを持つ行を抽出してやればいい。

ls -la /proc/*/{cwd,fd} | grep -C 10 'filepath' # lsの場合
find /proc/*/ -type l -printf '%p => %l\n' 2>/dev/null | grep -E '/proc/[0-9]+' | grep filepath # findの場合(こっちのほうがおすすめ)

blacknon@BS-PUB-UBUNTU-01:~$ ps -ef | grep tail
blacknon 14783 11210  0 09:21 pts/2    00:00:00 tail -F ./test.txt
blacknon 14785  8689  0 09:21 pts/1    00:00:00 grep --color=auto tail
blacknon@BS-PUB-UBUNTU-01:~$ find /proc/*/ -type l -printf '%p => %l\n' 2>/dev/null | grep -E '/proc/[0-9]+' | grep test.txt # findの場合(こっちのほうがおすすめ)
/proc/14783/task/14783/fd/3 => /home/blacknon/test.txt
/proc/14783/fd/3 => /home/blacknon/test.txt

ぱっと見でわかりにくいので、できればlsofなりfuserなりで調べるほうがいいかなーと思うのだけど、入ってない場合はこういった調べ方もありそうだ。