回答:
でファイルを読み取るたび/proc
に、カーネルでコードを呼び出して、ファイルの内容として読み取るテキストを計算します。コンテンツがオンザフライで生成されるという事実は、ほとんどすべてのファイルの時間が現在として報告され、サイズが0として報告される理由を説明します。ここでは0を「わからない」と読む必要があります。通常のファイルシステムとは異なり、にマウントされ/proc
ているprocfsと呼ばれるファイルシステムは、ディスクまたは他のストレージメディア(FAT、ext2、zfsなど)またはネットワーク(NFS、Sambaなど)からデータをロードしません。ユーザーコードを呼び出しません(FUSEとは異なります)。
Procfsは、ほとんどの非BSDユニックスに存在します。UNIXに関する第8版のAT&TのBell Labsで、プロセスに関する情報を報告する方法として始まりました(ps
多くの場合、情報を読み通すためのきれいなプリンターです/proc
)。ほとんどのprocfs実装には、/proc/123
PID 123のプロセスに関する情報を報告するために呼び出されるファイルまたはディレクトリがあります。Linuxは、例を含むシステムの状態を報告するさらに多くのエントリでprocファイルシステムを拡張します/proc/cpuinfo
。
過去に、Linux /proc
はドライバーに関する情報を提供するさまざまなファイルを取得していましたが、この使用は現在では廃止され/sys
、/proc
現在では徐々に進化しています。以下のようなエントリ/proc/bus
とは、/proc/fs/ext4
それらが下位互換性のためであるが、新しい同様のインターフェースを下に作成される残ります/sys
。この回答では、Linuxに焦点を当てます。
/proc
Linux に関するドキュメントの最初と2番目のエントリポイントは次のとおりです。
proc(5)
manページ。/proc
ファイルシステムでのカーネルのドキュメント。3番目のエントリポイントは、ドキュメントで説明されていない場合、ソースを読んでいます。マシンにソースをダウンロードできますが、これは巨大なプログラムであり、Linuxの相互参照であるLXRは大きな助けになります。(LXRには多くのバリアントがあります。実行中のバリアントがlxr.linux.no
はるかに優れていますが、残念ながらサイトがダウンしていることがよくあります。)Cの少しの知識が必要ですが、神秘的な値を追跡するためにプログラマである必要はありません。
/proc
エントリのコア処理はfs/proc
ディレクトリにあります。どのドライバーでもエントリを登録できます/proc
(上記のように、これはの代わりに推奨されなくなりました/sys
)fs/proc
。ドライバーはで宣言されinclude/linux/proc_fs.h
た関数を呼び出します。カーネルバージョン3.9までは、関数create_proc_entry
と一部のラッパー(特にcreate_proc_read_entry
)を提供し、カーネルバージョン3.10以降は、代わりに(およびそれ以上)のみproc_create
を提供しますproc_create_data
。
撮影/proc/cpuinfo
例として、の検索が"cpuinfo"
への呼び出しにあなたを導きproc_create("cpuinfo, …")
の中でfs/proc/cpuinfo.c
。コードはほとんど定型コードであることがわかります。ほとんどのファイルは/proc
テキストデータをダンプするだけなので、それを行うヘルパー関数があります。seq_operations
構造が存在するだけで、本当の意味はcpuinfo_op
データ構造にあります。データ構造はアーキテクチャに依存しており、通常はarch/<architecture>/kernel/setup.c
(または別のファイルで)定義されます。x86を例にとると、につながりますarch/x86/kernel/cpu/proc.c
。主な機能はshow_cpuinfo
、目的のファイルコンテンツを印刷します。インフラストラクチャの残りの部分は、データを要求した速度で読み取りプロセスに送ります。CPU周波数など、オンザフライで計算されたいくつかの数値を含む、カーネル内のさまざまな変数のデータから、オンザフライで組み立てられているデータを確認できます。
の大部分/proc
は、プロセスごとの情報です/proc/<PID>
。これらのエントリはfs/proc/base.c
、tgid_base_stuff
配列に登録されています。ここで登録されている一部の関数は、他のファイルで定義されています。これらのエントリが生成される方法の例をいくつか見てみましょう。
cmdline
はproc_pid_cmdline
、同じファイル内で生成されます。プロセス内のデータを見つけて出力します。clear_refs
、これまで見てきたエントリとは異なり、書き込み可能ですが、読み取り可能ではありません。したがって、proc_clear_refs_operations
構造はclear_refs_write
関数を定義しますが、読み取り関数は定義しません。cwd
はによって宣言されたシンボリックリンク(わずかに魔法のリンク)proc_cwd_link
であり、プロセスの現在のディレクトリを検索し、リンクコンテンツとして返します。fd
サブディレクトリです。ディレクトリ自体の操作はproc_fd_operations
データ構造で定義されます(エントリを列挙する関数を除き、それらはproc_readfd
プロセスの開いているファイルを列挙します)。エントリの操作は`proc_fd_inode_operationsにあります。の別の重要な領域/proc
は/proc/sys
、に対する直接のインターフェースsysctl
です。この階層のエントリから読み取ると、対応するsysctl値の値が返され、書き込むとsysctl値が設定されます。sysctlのエントリポイントはにありfs/proc/proc_sysctl.c
ます。Sysctlには、register_sysctl
友人や友人との独自の登録システムがあります。
あなたの親友が舞台裏でどんな魔法が起きているのかを見抜くときstrace
。このツールを操作することを学ぶことは、舞台裏でクレイジーマジックが起こっていることをよりよく理解するためにできる最善のことの1つです。
$ strace -s 200 -m strace.log cat /proc/cpuinfo
...
read(3, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU M 560 @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 65536) = 3464
write(1, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU M 560 @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 3464) = 3464
read(3, "", 65536) = 0
close(3) = 0
...
上記の出力から、それ/proc/cpuinfo
は単なる通常のファイルであるか、少なくとも1つのファイルのように見えることがわかります。深く掘り下げましょう。
ファイル自体を見ると、「単なるファイル」のように見えます。
$ ls -l /proc/cpuinfo
-r--r--r--. 1 root root 0 Mar 26 22:45 /proc/cpuinfo
しかし、よく見てください。ファイルのサイズが0バイトであることに注意してください。
#2-統計情報付きを使用してファイルを見ると、stat
何か特別なものがあるという次のヒントを得ることができます/proc/cpuinfo
。
$ stat /proc/cpuinfo
File: ‘/proc/cpuinfo’
Size: 0 Blocks: 0 IO Block: 1024 regular empty file
Device: 3h/3dInode: 4026532023 Links: 1
Access: (0444/-r--r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:18.390753719 -0400
Modify: 2014-03-26 22:46:18.390753719 -0400
Change: 2014-03-26 22:46:18.390753719 -0400
Birth: -
実行#2
$ stat /proc/cpuinfo
File: ‘/proc/cpuinfo’
Size: 0 Blocks: 0 IO Block: 1024 regular empty file
Device: 3h/3dInode: 4026532023 Links: 1
Access: (0444/-r--r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:19.945753704 -0400
Modify: 2014-03-26 22:46:19.945753704 -0400
Change: 2014-03-26 22:46:19.945753704 -0400
Birth: -
アクセス、変更、および変更の時間に注目してください。アクセスごとに変化し続けます。これは、3つすべてがそのように変更されることは非常に珍しいことです。ファイルのタイムスタンプ属性を編集しない限り、通常は同じままです。
#3-ファイル付き..このファイルが通常のファイル以外のものであるという別の手がかり:
$ file /proc/cpuinfo
/proc/cpuinfo: empty
名前付きパイプが何らかの形で現れた場合、これらのファイルのいずれかと同様に表示されます。
$ ls -l /dev/initctl /dev/zero
prw-------. 1 root root 0 Mar 26 20:09 /dev/initctl
crw-rw-rw-. 1 root root 1, 5 Mar 27 00:39 /dev/zero
$ file /dev/initctl /dev/zero
/dev/initctl: fifo (named pipe)
/dev/zero: character special
をタッチするemptyfile
と/proc/cpuinfo
、パイプよりもファイルのように見えます。
$ touch emptyfile
$ ls -l emptyfile
-rw-rw-r--. 1 saml saml 0 Mar 27 07:40 emptyfile
$ file emptyfile
emptyfile: empty
#4-マウント付き..
そのため、この時点で一歩後退し、少しズームアウトする必要があります。特定のファイルを見ていますが、おそらくこのファイルが存在するファイルシステムを見るべきでしょう。そして、このためにmount
コマンドを使用できます。
$ mount | grep " /proc "
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
OK、ファイルシステムのタイプはtype proc
です。/proc
異なるファイルシステムのタイプも同様です。これは、下にあるファイル/proc
が特別であるというヒントです。それらは、あなたのミルファイルの実行だけではありません。それでは、proc
ファイルシステムを特別なものにするための詳細情報を見つけましょう。
見撮影mount
のmanページを:
procファイルシステムは特別なデバイスに関連付けられていないため、マウントするときに、デバイス仕様の代わりにprocなどの任意のキーワードを使用できます。(慣習的な選択肢noneはそれほど幸運ではありません:umountからの「none busy」というエラーメッセージは混乱を招く可能性があります。)
そして、proc
のmanページを見ると:
procファイルシステムは、カーネルデータ構造へのインターフェイスとして使用される擬似ファイルシステムです。通常、/ procにマウントされます。ほとんどは読み取り専用ですが、一部のファイルではカーネル変数を変更できます。
同じmanページのもう少し下の部分:
/ proc / cpuinfo
これは、CPUおよびシステムアーキテクチャに依存する項目のコレクションであり、サポートされる各アーキテクチャごとに異なるリストがあります。2つの一般的なエントリは、CPU番号とbogomipsを提供するプロセッサです。カーネルの初期化中に計算されるシステム定数。SMPマシンには、各CPUの情報があります。lscpu(1)コマンドは、このファイルから情報を収集します。
マニュアルページの下部には、ここで見つけることができるカーネル文書への参照があります。タイトルは/ proc FILESYSTEMです。その文書からの引用:
procファイルシステムは、カーネルの内部データ構造へのインターフェイスとして機能します。システムに関する情報を取得し、実行時に特定のカーネルパラメータを変更するために使用できます(sysctl)。
ここで何を学びましたか?まあその与えられた/proc
疑似ファイルシステムとも、「内部データ構造へのインタフェース」と呼ばれ、それはその中の項目があると仮定するのはおそらく安全ですではない実際のファイルではなく、ただ症状は、ファイルのように見えるように作られたが、実際にはありません。
この引用は、man 5 proc
2004年頃の以前のバージョンに 含まれていたようですが、何らかの理由で含まれなくなりました。注:それが何であるかを非常にうまく説明しているため、なぜ削除されたのかわかりません/proc
:
GNU / Linuxシステムの/ procディレクトリは、カーネルへのインターフェースのようなファイルシステムを提供します。これにより、アプリケーションとユーザーは、通常のファイルシステムI / O操作を使用して、カーネルから情報を取得し、カーネルの値を設定できます。
procファイルシステムは、プロセス情報擬似ファイルシステムと呼ばれることもあります。「実際の」ファイルではなく、ランタイムシステム情報(システムメモリ、マウントされたデバイス、ハードウェア構成など)が含まれます。このため、カーネルの制御および情報センターと見なすことができます。実際、非常に多くのシステムユーティリティは、このディレクトリ内のファイルへの呼び出しにすぎません。たとえば、カーネルによってロードされたモジュールをリストするコマンドlsmodは基本的に「cat / proc / modules」と同じですが、システムのPCIバスに接続されているデバイスをリストするlspciは「cat / proc proc / pci '。このディレクトリにあるファイルを変更することにより、システムの実行中にカーネルパラメーターを変更できます。
ソース: proc疑似ファイルシステム
strace -o catcpuproc.txt cat /proc/cpuinfo
@slmの答えは非常に包括的なものですが、もっと簡単な説明は視点の変化から来るのではないかと思います。
日々の使用では、ファイルを物理的なものと考えることができます。一部のデバイスに保存されたデータのチャンク。これにより、/ proc / cpuinfoのようなファイルは非常に神秘的でわかりにくくなります。ただし、ファイルをインターフェイスと考えると、すべてが完全に理にかなっています。プログラムの内外にデータを送信する方法。
この方法でデータを送受信するプログラムは、ファイルシステムまたはドライバーです(これらの用語の定義方法によっては、定義が広すぎるか狭すぎる場合があります)。重要な点は、これらのプログラムの一部はハードウェアデバイスを使用して、このインターフェイスを介して送信されたデータを保存および取得することです。すべてではありません。
ストレージデバイスを(少なくとも直接)使用しないファイルシステムの例を次に示します。
Plan9 OS(http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs)は、一般的なプログラミングインターフェイスとしてファイルを使用する極端な例です。