Linux/Unixのファイル特性は何ですか?
ファイルは通常のファイル、ディレクトリ、シンボリックリンク、デバイスファイル、ソケット、管路、先入選出、そして私が恋しい以上。たとえば、シンボリックリンクは次のようになります。
$ sudo file /proc/22277/fd/23
/proc/22277/fd/23: broken symbolic link to socket:[7540288]
ソケット:
$ sudo ls -l /run/user/1001/systemd/notify
srwxrwxr-x 1 testme testme 0 Feb 6 16:41 /run/user/1001/systemd/notify
以下の特徴を持つファイルですインデックスノード(メモリまたはセカンダリストレージデバイスの一部のファイルシステムのinode?)すべてのファイルタイプにinodeがありますか? (どちらの質問でもそうだと思います。)
Linuxインターネットドメインソケット、トランスポートプロトコル(TCP / UDP)ソケットとポート開いたファイルの説明があるのがファイルだと言うようです。開かれたファイル記述のあるエントリには必ずinodeが必要ですか?
開いたファイルの説明はファイルよりも優れているため、「ファイル」を定義することはできません。ネットワークソケットとUnixドメインソケットの両方が開かれたファイル記述です。 UDSはディスク上の何かに関連付けることができます(これに影響を与える可能性がある条件はたくさんあります)。 NSはディスクの何も接続しません。
ありがとうございます。
答え1
長い話を短く
- ファイルは、一部またはすべての基本操作(開く、読み取り、書き込み、閉じる)を実行できるオブジェクトであり、inodeにメタデータが格納されています。
- ファイル記述子はこれらのオブジェクトへの参照です。
- 開いたファイルの説明(たとえば、開いている部分が重要です)は次のとおりです。どのようにファイル(少なくとも1つのファイル記述子で表されます)が開いています。
抽象化としてのドキュメント
相談しようPOSIX 定義 2017, セクション 3.164Fileの定義方法は次のとおりです。
書き込み、読み取り、または両方を行うことができるオブジェクト。ファイルには、アクセス権とタイプを含む特定の属性があります。ファイルタイプには、汎用ファイル、文字特殊ファイル、ブロック特殊ファイル、FIFO特殊ファイル、シンボリックリンク、ソケット、およびディレクトリが含まれます。実装では、他の種類のファイルをサポートできます。
したがって、ファイルは私たちが読んだり書いたりすることができます。みんな家に帰ってください。イベントは終了しました!
まあ、そんなに速くないです。これらの定義は関連概念のための多くのスペースを開き、一般的なファイルとパイプラインの間に明らかな違いがあります。 「すべてがファイルである」はそれ自体が概念であるデザインパターン文字通りの声明ではなく。このパターンに基づいて、ディレクトリ、パイプ、デバイスファイル、メモリファイル、ソケットなどのファイルタイプはすべて一連のシステムコールを介して操作できます(たとえば、open()
ソケットopenat()
の場合、USBの場合は一貫した方法で)。さまざまなデバイスがありますが、すべてがまったく同じUSBポートに接続されています(実際にはAからCまで、さまざまな種類のUSBポートタイプがありますが、アイデアを得ることができます)。write()
recv()
send()
もちろん、これが機能するためには、一貫した方法で実際のデータへの一種のインタフェースまたは参照が必要です。ファイル記述子:
ファイルアクセス用に開いているファイルを識別するプロセスごとに一意の負以外の整数。新しく作成されたファイル記述子は、0から{OPEN_MAX}-1までの値を持ちます。
したがって、write()
通常のファイルに書き込むのと同じ方法で、ファイル記述子1を介してSTDOUTにアクセスできます/home/user/foobar.txt
。ファイルにアクセスすると、open()
ファイル記述子を取得し、write()
同じ機能を使用してファイルに書き込むことができます。これがUnixの最初の創始者に対処しようとしたことです。まさにミニマリズムと一貫した動作です。これにより、command > /home/user/foobar.txt
シェルは参照されたファイル記述子をコピーしてfoobar.txt
ファイル記述子1(echoのSTDOUT)に渡すか、command
より正確にはコマンドを実行してからdup2(3,1)
コマンドexecve()
を実行します。しかし、それにもかかわらず、command
何も起こらなかったように、ファイル記述子1に同じ書き込みシステムコールが使用され続けます。
もちろん、ほとんどのユーザーがファイルだと思うほど、ディスクファイルシステムの一般的なファイルだと思います。これはさらに一致します。一般ファイル定義、セクション3.323:
システムが追加の構造を適用せずにランダムにアクセスできるバイトシーケンスであるファイル。
対照的に、私たちはソケット:
POSIX.1-2017のシステムインタフェースボリュームで説明されているように、プロセス間通信のための通信エンドポイントとして使用される特定の種類のファイル。
タイプに関係なく、さまざまなファイルタイプに対して実行できる操作は概念的に同じです(開く、読み取り、書き込み、閉じる)。
すべてのファイルにはinodeがあります。
ファイル定義で注目すべき点は、ファイルにinodeに格納される「特定の属性」があることです。実際、特にLinuxでは、以下を参照できます。inode(7) マニュアル最初の行:
各ファイルには、ファイルのメタデータを含むinodeがあります。アプリケーションはstat(2)(または関連する呼び出し)を使用してこのメタデータを取得できます。
繁栄。明確で直接的です。私たちにとって最もよく知られているinodeは、ディスク上のデータブロックとディレクトリに格納されているファイル名の間のブリッジです(ディレクトリはファイル名とそのinodeのリストにすぎないからです)。でも仮想ファイルシステムたとえば、カーネルの Pipefs と sockfs では inode を見つけることができます。次のコードスニペットを例に挙げます。
static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen)
{
return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]",
dentry->d_inode->i_ino);
}
ファイルを開く手順
これは完全に混乱しているので、Linux / Unixは「オープンファイルの説明」という機能を導入しました。スティーブン・チャジェラスの言葉によると、
ファイル自体ではなく、ファイルがどのように開かれたかについての履歴に近い。
そしてそれにPOSIXの定義:
プロセスまたはプロセスグループがファイルにアクセスした方法の履歴。各ファイル記述子は1つのオープンファイル記述を正確に参照しますが、オープンファイル記述は複数のファイル記述子で参照できます。ファイルオフセット、ファイル状態、およびファイルアクセスモードは、オープンファイル記述の属性です。
今私たちも見るとLinuxカーネルについて学ぶ本で著者はこう指摘する。
Linux は次の BSD ソケットを実装します。ソックスファイルシステム特別なファイルシステム...もっと正確に言えば、新しいBSDソケットごとに、カーネルは次のことを行います。ソックスファイルシステム特殊ファイルシステム
これを覚えてソケットはファイル記述子でも参照されます。したがって、カーネルのソケットに関連するオープンファイル記述があり、ソケットがファイルであると結論付けることができます。
続きます。 。 。おそらく
答え2
ファイルとは何ですか?
Linuxのファイルは基本的に対話できるものです。合計7種類のファイル形式があります。
- ソケット、
- シンボリックリンク、
- 一般ファイル、
- ブロックデバイス、
- 目次、
- キャラクターデバイス、
- FIFO(別名パイプ)。
状況によっては、ファイルについて別の方法で話しているため、多くの混乱が発生します。この議論には2つの異なるコンテキストがあります。
- ディスクに表示されるファイル(ファイルシステム)
- Linuxでのファイル表現(「メモリ内」)
Linux(メモリ内)
Linux(メモリ内)では、すべてのファイルが(それともそうかもしれませんか?)インデックスノード。このファイルが何であるかをLinuxに知らせるinodeなので、1つが必要です。 inodeを意味のあるコンテンツ(ディスク上のファイルなど)に再接続するために、inodeは3つの主要な情報を保存します。
- デバイスID - ファイルを担当するファイルシステムまたはドライバへの参照
- inode番号 - ファイルシステムまたはドライバによって割り当てられた一意の番号。 2つのinodeが異なるデバイスIDを持つ場合、同じinode番号を持つことができます。
- Type - Linuxにこのファイルが実際に何であるかを伝えます。探す。
ファイルとやり取りする方法は、ファイルの種類によって異なります。たとえば、ディレクトリを一覧表示できますが、デバイスをブロックすることはできません。ソケットには接続できますが、通常のファイルには接続できません。
ディスク上
他のファイルシステムは非常に異なります。 ext4のようなファイルシステムはunixとlinux用に書かれており、inodeの概念を反映しています。したがって、インメモリ inode は、オンディスク inode で読み取られるのとほぼ同じです。
しかし、彼らは異なります。たとえば、ディスクの inode にデバイス ID がないか、必要です。 Linuxオンメモリinode(インメモリ)は、ファイルデータがディスクに保存されている場所を追跡する必要があります。 LinuxのInodeは、この問題を解決するためにドライバに依存しています。
ディスク上の inode 番号は通常、ドライバの Linux の inode 番号として使用されます。したがって、ディスクの inode はメモリの inode として誤解されます。
ファイル(インデックスノード)をどのように参照しますか?
ファイル名
ファイル名は、ファイルを参照(検索)する最も使いやすい方法です。ファイルシステムは、Linuxが使用するファイル名ツリーを保存しますmount
。ツリーの各名前は1つのインデックスノードのみを指します。
Linux のファイルは複数のファイル名を持つことができます。これは、ファイルシステムでもサポートされている場合にのみ可能です。 Linuxでもディスクでも同じinodeを指す複数の名前を持つことで、複数のファイル名(ハードリンク)が実装されます。
ファイルを削除すると、そのファイル名のみが削除されます。実際の占有スペースは、すべてのファイル名が削除され、すべての「ファイル記述子」が閉じられた場合にのみ回収できます。
したがって、ディスク上の一般ファイルには3つあります。ファイル名 - > inode - >データ
ファイル記述子
プログラムがファイルを開くと、ファイル名がファイル記述子(数字)に置き換えられます。これは名前やパスを持たないinodeへの別のリンクです。ファイルに対するすべての操作(例:「読み取り」および「書き込み」)は、ファイル名の代わりにファイル記述子を使用します。
ファイル記述子はopen()を介して取得する必要はありません。ファイル記述子があれば、子プロセスから継承(コピー)したり(unixドメインソケットを介して)まったく別のプロセスにコピーしたりできます。
OPで引用されたコメントで「ファイルの説明」という用語を使用したので、これは少し混乱を引き起こしたと思います。私はこのコメントがファイル記述子が単純な数字以上であることを説明したいと思います。しかし、彼らはこれを混乱した方法で表現します。
ファイル名やファイルシステムのないファイル
このモデルにはいくつかの特徴があります。まず、ファイルを開いて削除すると(ファイルを閉じずに)、開かれたファイル記述子がディスク上のファイルを回復するのを防ぎます。これにより、ファイル名のないファイルが作成されます。
これ以上のことは、一部のファイルがファイルシステムに属していないことです。プログラムは無名パイプまたは名前のないスコット。 Linuxにはinodeがありますが、Linuxカーネルにのみ存在するため、ファイルシステムに直接接続されません。これらはまだファイルです(奇妙ですが)。 inodeを参照するファイル記述子があります。
名前のないパイプの一般的な例は、コマンドラインプログラムのSTDIN、STDOUTです。パイプ(foo | bar
)を介して2つのプログラムを接続すると、2つのプログラム間のパイプは名前のないパイプになります。
結論
多くの場合、これらの概念をすべてまとめて「ファイル」という単語を使用します。通常、別々のファイル名、ディスクのファイル名に変換されるinode、ディスクのinode、そして最終的にディスクにコンテンツを書き込むことに気を使わずに「ファイルに書き込む」ことができます。 「ファイルに書き込む」という用語は、これらすべてを意味します。
特別な場合にのみ、これらの概念を分離する必要があります。
答え3
1)Unixのほとんどのファイルシステムでは、ファイル、fifo、ディレクトリなどはinodeで記述されています。 inodeには多くのフィールドがありますが、この場合最も興味深いのはi_modeフィールドです。権限の横には、inodeが指す「ファイル」タイプが含まれています。
Constant Value Description
-- file format --
EXT2_S_IFSOCK 0xC000 socket
EXT2_S_IFLNK 0xA000 symbolic link
EXT2_S_IFREG 0x8000 regular file
EXT2_S_IFBLK 0x6000 block device
EXT2_S_IFDIR 0x4000 directory
EXT2_S_IFCHR 0x2000 character device
EXT2_S_IFIFO 0x1000 fifo
2)どのように見ているかによって異なります。 「実際の」ファイルであれ、他の構成(たとえば、名前のないパイプ)でも、開いているすべてのファイルに対してシステムコールを介してinodeを取得できます。ただし、ファイルハンドルが閉じられると、inodeは使用できません。 (事実上の不正確さを排除するためにセクション2が編集されています)