/ devをcatできるのはなぜですか?


41

できるcat /dev、できるls /dev、できないless /dev。なぜこのディレクトリをcat許可しcat、他のディレクトリは許可しないのですか?

zshでのこの動作の図。


@KamilMaciorowski、ここに出力とneofetch情報があります:) i.imgur.com/3azpnDt.png
haboutnnah

回答:


43

歴史的に(V7 UNIXまで、または1979年頃)、readシステムコールはファイルとディレクトリの両方で機能していました。readディレクトリでは、ユーザープログラムがディレクトリエントリを取得するために解析する単純なデータ構造を返します。実際、V7 lsツールはまさにこれをread行いました。ディレクトリ上で、結果のデータ構造を解析し、構造化リスト形式で出力します。

ファイルシステムがより複雑になると、この「単純な」データ構造はより複雑になり、readdirプログラムがの出力を解析できるようにライブラリ関数が追加されましたread(directory)。システムやファイルシステムが異なれば、ディスク上のフォーマットも異なる可能性があり、複雑になりました。

SunがNetwork File System(NFS)を導入したとき、彼らはディスク上のディレクトリ構造を完全に抽象化することを望んでいました。read(directory)ただし、プラットフォームに依存しないディレクトリの表現を返す代わりに、新しいシステムコールを追加しましたgetdirents-- readネットワークにマウントされたディレクトリで禁止されました。このシステムコールは、さまざまなUNIXフレーバーのすべてのディレクトリで動作するように急速に適応され、ディレクトリの内容を取得するデフォルトの方法になりました。(https://utcc.utoronto.ca/~cks/space/blog/unix/ReaddirHistoryから抽出された履歴)

readdir現在、ディレクトリを読み取るためのデフォルトの方法であるため、read(directory)通常、ほとんどの最新のOSで実装されていません(-EISDIRを返します)(たとえば、QNXはreaddirとして実装する注目すべき例外read(directory)です)。ただし、最新のカーネルの「仮想ファイルシステム」設計では、ディレクトリの読み取りが機能するかどうかは、実際には個々のファイルシステム次第です。

実際、macOSでは、マウントポイントのdevfs基礎となるファイルシステムは/dev実際に読み取りをサポートしています(https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/bsd/miscfs/devfs/devfs_vnops.c#L629) :

static int
devfs_read(struct vnop_read_args *ap)
{
        devnode_t * dn_p = VTODN(ap->a_vp);

    switch (ap->a_vp->v_type) {
      case VDIR: {
          dn_p->dn_access = 1;

          return VNOP_READDIR(ap->a_vp, ap->a_uio, 0, NULL, NULL, ap->a_context);

これはREADDIR、読み込もうとすると明示的に呼び出されます/dev(ファイルの読み取り/devは別の関数で処理されます- devfsspec_read)。したがって、プログラムがreadシステムコールonを呼び出すと、プログラム/devは成功し、ディレクトリリストを取得します!

これは事実上、UNIXの非常に初期の時代からのホールドオーバーであり、非常に長い間触れられていない機能です。私の一部は、これが何らかの後方互換性の理由で保持されていると疑っていますが、実際には何も傷つけていないので、誰も機能を削除することを気にしないという事実である可能性があります。


ほとんどのディレクトリから削除されているため、おそらく後者です。
user253751

36

Lessはテキストファイルビューアーであり、catは任意のデータをコピーするためのツールです。そのため、lessは独自のチェックを実行して、大量のデータを持つものや非常に奇妙な動作をするものを開かないようにします。一方、catにはそのようなチェックがまったくありません。カーネルが何かを開くことを許可する場合(パイプやデバイス、さらに悪いものであっても)、catはそれを読み取ります。

では、なぜOSはcatがディレクトリを開くことを許可するのですか?従来のBSDスタイルのシステムでは、すべてのディレクトリをファイルとして読み取ることができました。それは、プログラムが最初にディレクトリをリストする方法でした。ディスクに保存された異なる構造を解釈するだけです。

後に、それらのディスク上の構造は、カーネルが使用するディレントから分岐し始めました。以前はディレクトリが線形​​リストでしたが、後のファイルシステムはハッシュテーブル、Bツリーなどを使用し始めました。そのため、ディレクトリを直接読み取ることはもはや簡単ではありませんでした–カーネルはこのための専用機能を増やしました。(それが主な理由であったのか、それとも主にキャッシングなどの他の理由で追加されたのかはわかりません。)

一部のBSDシステムでは、引き続きすべてのディレクトリを読み取り用に開くことができます。ディスクから生データを提供するのか、エミュレートされたdirentリストを代わりに返すのか、ファイルシステムドライバーに決定させるのかはわかりません。

したがって、おそらくmacOSは、ファイルシステムがデータを提供する限り、カーネルが許可するオペレーティングシステムの1つです。違いは、初期にはこれを可能にするために作成さ/devれたdevfsファイルシステム上にあるのに対し/、現代ではこの機能が不要であるAPFSファイルシステム上にあるということです。

免責事項:私は実際にBSDまたはmacOSに関する研究を行っていません。私はちょうどそれを翼にしている。


これは理にかなっているようです。標準のOSファイルシステムと異なるストレージの他のセクションはありますか?私は/etcそうするだろうと思ったので、それをベンチマークとして使用しました。
-haboutnnah

2
それどころか、一般的に/ etcは通常のファイルを含む通常のフォルダーです。ただし、他の仮想ファイルシステムが存在する場合があります。実行するmount/sbin/mount、現在どこにマウントされているかを確認します。
荒廃

あなたが正しい!これを参照してください:i.imgur.com/pcVpo1o.png
haboutnnah

これは本当にすてきな@ grawity、i.imgur.com / 8QuR0FK.png
haboutnnah

6
@haboutnnahスクリーンショット/devは、devfsそれ/etcがドライバーを使用している仮想ファイルシステムであるのに対し、ドライバーを使用している/ファイルシステムの一部であることを確認しますapfs。そのため、理由catは1つを読み、もう1つは読みません。ドライバーapfsdevfsドライバーの違いです。
カスペルド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.