これは、知っておくべきUnixやLinuxのユーティリティーに関するシリーズの3番目の記事です。この記事では、便利な lsof
ツールについてお伝えしようと思います。 netcat
がネットワーク接続のスイスアーミーナイフ(訳注 : 何でもできる便利なツールの意味)なら、 lsof
はUnixのデバッグのスイスアーミーナイフであると言いたいところです。
lsof
はUnix哲学に忠実に従っています。ひとつのタスクだけを完璧にこなす、つまり、プロセスによって開かれているファイルの情報を一覧にするだけです。開かれているファイルとは、通常のファイル、ディレクトリー、NFSのファイル、ブロックファイル、キャラクタースペシャルファイル、共有ライブラリー、パイプ、名前付きパイプ、シンボリックリンク、ソケットストリーム、インターネットソケット、Unixドメインソケットなどなどたくさんあります。Unixにおいてはほとんど何でもファイルなので、 lsof
がいかに便利か想像できるでしょう!
このシリーズを見始めるなら、最初の記事であるパイプビューア(pv)を確認してみてください。こういう感じの記事に興味があれば、今後の記事を自動的にチェックできるように私のRSSフィードを購読する事をお勧めします。
lsofの使い方
この記事では、考え付く限りたくさんのユースケースを元に、 lsof
について書いていこうと思います。(もう知っているかもしれませんが)一番シンプルな方法から始めて、複雑なものに進んでいきましょう。
開かれているファイル全てを表示
lsof
lsof
を引数なしで実行すると、各プロセスが開いているファイル全てを一覧表示します。
どのプロセスがファイルを使用しているか確認
lsof /path/to/file
ファイルのパスを引数に渡すと、 lsof
はファイルを使っている全プロセスを一覧表示します。
また、複数のファイルを指定すると、それらのファイルを使っている全プロセスを表示します。
lsof /path/to/file1 /path/to/file2
ディレクトリを再帰的にたどって開かれているファイルを表示
lsof +D /usr/lib
+D
引数を渡すと、 lsof
は指定したディレクトリとそのサブディレクトリ全ての中から開かれているファイルを一覧表示します。
ただし、この方法は grep
を使ったやり方よりも遅いことに注意してください。
lsof | grep '/usr/lib'
これは、 lsof +D
はまず個々のファイルチェックしてからそれを表示するためです。
ユーザーごとに開かれているファイルを一覧表示
lsof -u pkrumins
-u
オプション(userの頭文字)は、ユーザー pkrumins
によって開かれているファイルだけを出力するよう制限します。
複数のユーザーをコンマ区切りのリストにして渡すこともできます。
lsof -u rms,root
これは、ユーザー rms
と root
によって開かれているファイルを一覧表示します。
あるいは、 -u
を2回付けても同じことができます。
lsof -u rms -u root
プログラム名ごとに開かれているファイルを探す
lsof -c apache
-c
オプションで、名前が apache
から始まるプロセスの開いているファイルを選べます。
つまり、以下のように書いたのと同じです。
lsof | grep foo
これは以下のように短くできます。
lsof -c foo
実際には、探しているプロセスの最初の部分だけを指定すればよいでしょう。
lsof -c apa
これで、 apa
から始まるプロセスが開いているファイル全てを一覧表示できます。
また、複数の -c
オプションを付けて複数のプロセスが開いているファイルを出力することもできます。
lsof -c apache -c python
これは、 apache
と python
が開いているファイルを一覧表示します。
あるユーザーまたはプロセスが開いているすべてのファイルを一覧表示
lsof -u pkrumins -c apache
lsof
のオプションは組み合わせて使えます。デフォルトでは複数のオプションがORになります。つまり -u pkrumins
と -c apache
の組み合わせは、 pkrumins
が開いているすべてのファイルと、 apache
が開いているすべてのファイルを合わせた一覧を返します。
あるユーザーの特定プロセスが開いているすべてのファイルを一覧表示
lsof -a -u pkrumins -c bash
-a
オプションに注意してください。これがオプションをANDでつなぎます。出力は、 pkrumins
ユーザーのもとで動いている bash
で開かれているファイルの一覧になります。
root以外のすべてのユーザーが開いているファイルを一覧表示
lsof -u ^root
rootユーザー名の前の^
に注意してください。パターンに一致しないものを抽出するので、 lsof
はrootでない全ユーザーが開いている全ファイルを出力します。
PID指定でプロセスが開いているすべてのファイルを一覧表示
lsof -p 1
-p
オプション(PIDから来たもの)が、PIDで出力のファイル一覧をフィルターします。
PIDのコンマ区切り指定、あるいは複数回 -p
を引数に渡すことで複数のPIDを指定できます。
lsof -p 450,980,333
これは、PIDが450、980、333のプロセスが開いているすべてのファイルを一覧表示します。
lsof -p ^1
ここでも否定を表す ^
が使われています。PID 1のプロセスが開いているファイルを含まないリストが表示されます。
すべてのネットワーク接続を一覧表示
lsof -i
-i
オプションを付けた lsof
は、開いているインターネットソケット(TCPとUDP)と一緒に全プロセスの一覧を表示します。
すべてのTCPネットワーク接続を一覧表示
lsof -i tcp
-i
引数はいくつかのオプションを取れますが、その中のひとつが tcp
です。 tcp
オプションはTCPソケットを開いているプロセスだけを一覧表示します。
すべてのUDPネットワーク接続を一覧表示
lsof -i udp
udp
オプションは、 lsof
にUDPソケットを使っているプロセスだけを表示させます。
誰がポートを使っているか調べる
lsof -i :25
-i
に :25
オプションを追加すると、 lsof
はTCPあるいはUDPの25万ポートを使っているプロセスを見つけ出します。
また、サービスポート名(/etc/servicesに書かれています)をポート名の代わりに書くこともできます。
lsof -i :smtp
誰が特定のUDPポートを使っているか調べる
lsof -i udp:53
同じく誰がTCPポートを使っているかを調べるには、
lsof -i tcp:80
特定のユーザーによるすべてのネットワーク通信を調べる
lsof -a -u hacker -i
ユーザーhackerが使用しているネットワークファイルすべての一覧を生成するのに、-a
オプションが -u
と -i
を結合します。
すべてのNFSファイルを一覧表示
lsof -N
このオプションはNFSの -N
なので覚えやすいでしょう。
すべてのUnixドメインソケットファイルを一覧表示
lsof -U
このオプションもUnixの -U
なので覚えやすいでしょう。
特定のグループIDのプロセスに対するすべてのファイルを一覧表示
lsof -g 1234
プロセスグループは、プロセスを論理的にグループ化するのに使われます。この例では、PGID 1234のプロセスに開かれているすべてのファイルを調べます。
特定のファイルディスクリプターに関連付いたすべてのファイルを一覧表示
lsof -d 2
これはファイルディスクリプター2として開かれたすべてのファイルを一覧表示します。
ファイルディスクリプターの範囲も指定できます。
lsof -d 0-2
これはファイルディスクリプター0、1、2のいずれかで開かれたファイルを表示します。
この他にも、メモリーマップドファイルを一覧表示する mem
のような特別な値もたくさんあります。
lsof -d mem
txt
はメモリーにロードされて実行されたプログラムを表示します。
lsof -d txt
リソースを使用しているプロセスのPIDを表示する
lsof -t -i
-t
オプションはプロセスのPIDだけを表示します。 -i
と一緒に使うと、ネットワーク接続と一緒にすべてのプロセスのPIDを出力します。ネットワークを使用しているプロセス全部をkillするのに便利です。
kill -9 `lsof -t -i`
ファイル一覧を繰り返し表示する
lsof -r 1
-r
オプションは、割り込みがあるまで lsof
がファイルを表示し続けるようにします。引数の1は、1秒ごとに表示を繰り返すという意味です。このオプションは、特定ユーザーのネットワーク接続状況を監視するような、結果が小さくなるクエリーと組み合わせると威力を発揮します。
lsof -r 1 -u john -i -a
lsofのインストールの方法
lsof
は多くのUnixシステムでは初めからインストールされています。もしあなたの使っているシステムに入っていないなら、ソースからインストールしてみましょう。
BSDには、同じようなことができる独自のユーティリティーである fstat
があります。
lsof
の完全なドキュメントを探しているなら、 lsof
のman pageを見るか、 lsof -h
で簡単なチートシートを見ることもできます。