\r\n\r\n
Linuxのすべてがファイルだとしたら、ハードディスクにあるファイル以外にもいろいろあるはずです。このチュートリアルでは、lsofを使用して、ファイルとして扱われる他のすべてのデバイスとプロセスを確認する方法を紹介します。
よく引用される言葉に、「Linuxではすべてがファイルである」というものがあります。ファイルは、バイトの集合体です。プログラムに読み込まれたり、プリンタに送られたりすると、バイトのストリームを生成しているように見える。書き込むときは、バイトのストリームを受け取ります。
その他、キーボード、ソケット接続、プリンタ、通信プロセスなど、バイトストリームを受け付けたり生成したりするシステムコンポーネントが多数存在します。これらのデバイスは、バイトストリームを受け入れるか、生成するか、または受け入れて生成するため、あたかもファイルのように非常に低いレベルで処理することができる。
この設計思想は、Unixオペレーティングシステムの実装を簡素化するものです。つまり、小さなハンドラ、ツール、apiのセットを作成することで、様々な異なるリソースを扱うことができるのです。
ハードディスクにあるデータファイルやプログラムファイルは、ファイルシステム上の単なるファイルである。
ファイルとして扱われている他のプロセスやデバイスをすべて調べるにはどうしたらいいのでしょうか?lsofコマンドを使用します。システムで開いているファイルを一覧表示します。つまり、処理中のすべてのものを、あたかもファイルのように一覧表示するのです。
関連:Linuxにおける「everything is a file」の意味とは?
lsofが報告できるプロセスやデバイスの多くは、rootに属しているか、rootによって起動されているので、lsofにはsudoコマンドを使用する必要があります。
このリストは長くなるので、少ないパイプで行うことにします。
sudo lsof | lesslsof の出力が表示される前に、GNOME ユーザーはターミナル・ウィンドウに警告メッセージを表示することがあります。
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs Output information may be incomplete.lsof はマウントされたすべてのファイルシステムを処理しようとします。この警告メッセージの理由は、lsof が GNOME Virtual File System (GVFS) に遭遇したためです。ユーザースペースファイルシステム(FUSE)の特殊なケースです。GNOME とその API、そしてカーネルとの間の橋渡しの役割を果たします。これらのファイルシステムには、rootユーザーであっても、マウントした所有者(この場合はGNOME)以外はアクセスすることができません。この警告は無視していただいて結構です。
lsofの出力は非常に広い。一番左の列は
一番右の列は
すべての列がすべての種類のオープンファイルに適用されるわけではありません。いくつかの列が空白であることは正常です。
FD列のファイルディスクリプタは、多くのオプションのうちの1つであり、マニュアルページにはすべてのオプションが記載されています。
FDカラムのエントリは、ファイル記述子、パターン文字、ロック文字の3つの部分から構成されます。
モード文字は、以下のいずれかとする。
ロック文字は、次のいずれかの文字とすることができる。
タイプ欄には70以上の項目が表示されることがありますが、一般的な項目が表示されます。
あるファイルを開いているプロセスを表示するには、lsofの引数にファイル名を指定します。たとえば、オープンしたプロセスのカーネルログファイルを表示するには、次のコマンドを使用します。
sudo lsof /var/log/kern.loglsofは、ユーザーsyslogによって起動された単一のプロセス、rsyslogdを表示することによって応答します。
あるディレクトリから開かれたファイルとそれを開いたプロセスを見るには、lsofの引数にそのディレクトリを渡します。+D(ディレクトリ)オプションが必要です。
var/log/ディレクトリで開かれたすべてのファイルを表示するには、次のコマンドを使用します。
sudo lsof +D /var/log/lsof は、そのディレクトリにあるすべてのオープンファイルのリストで応答します。
ホームディレクトリから開かれたすべてのファイルを表示するには、次のコマンドを使用します。
sudo lsof +D /homeホームディレクトリから開かれたファイルを表示します。一部の列の記述が短いため、リスト全体が狭くなっていることに注意してください。
特定のプロセスが開いているファイルを見るには、-c (コマンド) オプションを使用します。なお、lsof には、一度に複数の検索項目を指定することができます。
sudo lsof -c ssh -c initlsof は、コマンドラインで指定されたプロセスのいずれかによって開かれたファイルの 一覧を提供します。
特定のユーザーによって開かれたファイルに表示を限定する場合は、-u(ユーザー)オプションを使用します。この例では、Maryが所有する、またはMaryの代わりに起動されたプロセスによって開かれたファイルを確認することになります。
sudo lsof -u maryリストアップされたすべてのファイルは、ユーザーMaryに代わって開かれたものです。これには、例えばデスクトップ環境によって開かれたファイルや、Maryがログインしているだけで開かれたファイルなどが含まれます。
ユーザーが開いたファイルを除外するには、"^"演算子を使用します。リストからユーザーを除外することで、興味のある情報を見つけやすくなります。従来通り-uオプションを使用し、ユーザー名の先頭に"^"文字を追加する必要があります。
sudo lsof +D /home -u ^maryこのとき、/homeディレクトリのリストには、ユーザーMaryが開いたファイルは含まれていません。
特定のプロセスによって開かれたファイルを一覧表示するには、-p(process)オプションを使用し、引数としてプロセスIDを指定します。
sudo lsof - p 4610指定されたプロセスIDで開かれたすべてのファイルがリストアップされます。
特定のファイルを開いたプロセスのプロセスIDを見るには、-t(省略)オプションを使い、コマンドラインでファイル名を指定します。
sudo lsof -t /usr/share/mime/mime.cacheプロセスIDが簡易一覧で表示されます。
ユーザーMaryが開いているSSHプロセスに関連するファイルをリストアップしてみましょう。コマンドラインで複数の検索語を指定できることは分かっているので、これは簡単なはずです。
sudo lsof -u mary -c sshlsofの出力を見てみましょう。これは正しくありません。出力にstarted by rootの項目があります。
これは予想外だ。どうだった?
複数の検索語を指定すると、lsofは最初の検索語または2番目の検索語に一致するファイルをすべて返し、以下同様となります。つまり、OR検索を行うのである。
lsofにAND検索をさせるには、-a(AND)オプションを使用します。つまり、最初の検索語と2番目の検索語に一致するファイルのみがリストアップされ、以下同様となります。
もう一度、-aオプションを使って試してみましょう。
sudo lsof -u mary -c ssh -aリスト内の各ファイルは、Maryによって、またはMaryの代わりに開かれ、SSHコマンドと関連付けられています。
repeatオプションは、+rと-rの2つの方法で適用できます。また、lsofが表示を更新するまでに待つ秒数を追加する必要があります。
どちらの形式でも repeat オプションを使用すると、lsof は通常通り結果を表示しますが、表示の下部に破線が追加されます。コマンドラインで指定された秒数だけ待機し、新しい結果で表示を更新します。
rオプションの場合は、Ctrl+Cを押すまで継続します。r形式の場合、表示する結果がなくなるまで、またはCtrl+Cを押すまで続けます。
sudo lsof -u mary -c ssh -a -r5リストの下にある点線に注意してください。これは、出力が更新されたときに、新しいデータの表示ごとに区切られます。
i(インターネット)オプションでは、ネットワークやインターネット接続に関連するプロセスによって開かれたファイルを表示することができます。
lsof -iネットワークやインターネット接続で開いたすべてのファイルが表示されます。
特定のプロセスIDに関連するインターネット接続によって開かれたファイルを見るには、-pオプションと-aオプションを追加します。
ここでは、インターネットやネットワーク接続で開かれたファイルを、プロセスID 606で検索しています。
sudo lsof -i -a -p 606インターネットまたはネットワーク接続に関連するファイルのうち、プロセスID 606によって開かれたファイルをすべて表示します。
特定のプロセスで開かれたファイルを探すには、-c(コマンド)オプションを使用することができます。インターネットまたはsshプロセスに関連するネットワーク接続によって開かれたファイルを見つけるには、次のコマンドを使用します。
lsof -i -a -c sshssh処理の結果として開かれたすべてのファイルが出力にリストされます。
インターネットやネットワーク接続で開かれたファイルの特定ポートに関するlsofレポートを行うことができます。そのために、:文字の後にポート番号を使用します。
ここでは、ネットワークやインターネット接続でポート22を使用して開かれたファイルをリストアップするようlsofに依頼します。
lsof -i :22リストアップされたすべてのファイルは、ポート22(SSH接続のデフォルトポート)に関連するプロセスによって開かれます。
特定のプロトコルを使用したネットワークやインターネット接続に関連するプロセスによって開かれたファイルを表示するようにlsofに依頼することができます。TCP、UDP、SMTPから選択することができる。TCPプロトコルを使って、何が得られるか見てみましょう。
sudo lsof -i tcpTCPプロトコルを使用するプロセスによって開かれたファイルのみがリストアップされます。
これは、lsofの一般的なユースケースの基礎となるものですが、それだけではありません。マニュアルページは2800行以上あるので、あとどの程度コンテンツが残っているのか判断できます。
lsofコマンドは、オープンファイルや擬似ファイルの地層を掘り下げることができます。模式図が用意されており、アトラスはマニュアルページにあります。