
Linux には、実際にはファイルではない特殊なファイルが存在します。
これらの最も顕著で明確な例はdev
、次のようなフォルダー内の「ファイル」です。
/dev/null
- ファイルに書き込んだ内容はすべて無視されます/dev/random
- ファイルの内容の代わりにランダムなデータを出力します/dev/tcp
- このファイルに書き込んだデータをネットワーク経由で送信します
まず、実際には何らかのスクリプトやバイナリを偽装したこれらの種類の「ファイル」の名前は何でしょうか?
次に、それらはどのように作成されるのでしょうか? これらのファイルはカーネル レベルでシステムに組み込まれているのでしょうか、それとも自分で「マジック ファイル」を作成する方法があるのでしょうか ( はどうでしょうか/dev/rickroll
)?
答え1
/dev/zero
「特別なファイル」の例です。特に「デバイスノード」です。通常、これらはディストリビューションのインストールプロセスで作成されますが、完全に必要に応じて自分で作成してください。
ls
以下について質問する場合/dev/zero
:
# ls -l /dev/zero
crw-rw-rw- 1 root root 1, 5 Nov 5 09:34 /dev/zero
先頭の「c」は、これが「キャラクタ デバイス」であることを示しています。もう 1 つのタイプは「ブロック デバイス」( ls
「b」と表示されます) です。大まかに言うと、ハードディスクなどのランダム アクセス デバイスはブロック デバイスである傾向があり、テープ ドライブやサウンド カードなどのシーケンシャル デバイスはキャラクタ デバイスである傾向があります。
「1, 5」の部分は「メジャーデバイス番号」と「マイナーデバイス番号」です。
この情報を使用して、mknod
コマンドを使用して独自のデバイス ノードを作成できます。
# mknod foobar c 1 5
foobar
これにより、現在のフォルダに という名前の新しいファイルが作成されます。その通りと同じです/dev/zero
。(もちろん、必要に応じて異なる権限を設定することもできます。) この「ファイル」に実際に含まれているのは、上記の 3 つの項目 (デバイス タイプ、メジャー番号、マイナー番号) だけです。 を使用して、ls
他のデバイスのコードを検索し、それらを再作成することもできます。 飽きたら、 を使用して、rm
作成したデバイス ノードを削除します。
基本的に、メジャー番号は Linux カーネルにどのデバイス ドライバーと通信するかを伝え、マイナー番号はデバイス ドライバーにどのデバイスについて通信するかを伝えます。(たとえば、SATA コントローラーは 1 つかもしれませんが、複数のハードディスクが接続されている可能性があります。)
あなたがしたい場合は発明する新しい機能を持つ新しいデバイス... そうですね、Linux カーネルのソース コードを編集して、独自のカスタム カーネルをコンパイルする必要があります。 なので、それはやめておきましょう! :-) ただし、既に持っているデバイス ファイルを複製して追加することはできます。 udev のような自動化システムは、基本的にデバイス イベントを監視し、自動的にmknod
/を呼び出すだけですrm
。 それ以上の魔法はありません。
まだあります他の特殊ファイルの種類:
Linux は、ディレクトリを特別な種類のファイルとみなします。(通常、ディレクトリを直接開くことはできませんが、もし開くことができた場合、ディレクトリが特別な形式のデータを含む通常のファイルであり、そのディレクトリ内のすべてのファイルの場所をカーネルに伝えることがわかります。)
シンボリックリンクは特別なファイルです。(ただし、ハードリンクはそうではありません。)
ln -s
コマンドを使用してシンボリックリンクを作成できます。(マニュアルページを参照してください。)「名前付きパイプ」または「FIFO」(先入先出キュー)と呼ばれるものもあります。 で作成できます
mkfifo
。 FIFOは、次の方法で開くことができる魔法のファイルです。二複数のプログラムを同時に実行します。1 つは読み取り、もう 1 つは書き込みです。この場合、通常のシェル パイプのように動作します。ただし、各プログラムを個別に起動することもできます...
いかなる意味でも「特別」ではないファイルは、「通常のファイル」と呼ばれます。Unix のドキュメントでこれについて言及されているのを時々見かけるでしょう。これが意味するところです。つまり、デバイス ノードやシンボリック リンクなどではないファイルです。魔法のような特性を持たない、通常の日常的なファイルです。
答え2
エントリのほとんどは、/dev
ブロック デバイス inode または文字デバイス inode です。Wikipediaには多くの詳細があるそれについては繰り返すつもりはありません。
しかし、/dev/tcp
あなたの質問で言及されている は、既存の回答のいずれにも説明されていません。/dev/tcp
および は、/dev/udp
他のほとんどのエントリとは異なります/dev
。 ブロック デバイスとキャラクタ デバイスはカーネルによって実装されますが、/dev/tcp
および は/dev/udp
ユーザー モードで実装されます。
bash シェルは、/dev/tcp
との実装を持つプログラムの 1 つです/dev/udp
( からコピーksh93
)。bash リダイレクト演算子を使用してそれらの下のパスを開こうとすると、通常のシステム コールは実行されませんopen
。代わりに、bash は TCP ソケットを作成し、指定されたポートに接続します。
bash
これはユーザーモードで実装されており、一部のプログラムでのみ実装されています。次の例では、letingとcat
try to openの違いを示しています。/dev/tcp/::1/22
$ cat /dev/tcp/::1/22
cat: /dev/tcp/::1/22: No such file or directory
$ cat < /dev/tcp/::1/22
SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.3
との違いはksh93
、 はリダイレクト演算子を使用して TCP 接続のみを実行し、や組み込み関数bash
のようにファイルを開く可能性のある他の場所では実行しないことです。source
.
答え3
他の回答で説明されているデバイスノード(ノッド(2)または、devfsLinuxには特別な方法で提供される他の「魔法の」ファイルもあります仮想ファイルシステム、特に/proc/
(参照プロセス(5)、読むプロセス)と/sys/
(について読むsysfs)。
これらの疑似ファイル(例えば、統計(2)- デバイスとしてではなく、通常のファイルとして)はカーネルによって提供される仮想ビューです。特に、/proc/
(例えばcat /proc/$$/maps
、またはによって)からの読み取りは、開く(2)/proc/self/status
プログラム内での-ing は通常、ディスクやネットワークからの物理的な I/O を伴わないため、非常に高速です。
追加の疑似ファイルを作成するには、/proc/
通常、独自のものを作成する必要があります。カーネルモジュールそれをロードします(例:これ)。
答え4
他のユーザーがすでに詳しく説明しているように、特殊ファイルにはバックアップ用のコードが必要です。しかし、Linux ではユーザー空間でそのコードを記述する方法がいくつか提供されていることに誰も言及していないようです。
A. ヒューズ/proc
(USErspaceのファイルシステム)を使用すると、カーネルをクラッシュさせるリスクなしに、任意の言語/ランタイムで次のようなものを書くことができます。行く、Node.js、パール、PHP の、パイソン、 ルビー、さび、等。
sudo
また、FUSE ファイルシステムはマウントを行うユーザーとして実行されるため、マウントしなくてもよいという利点もあります。
FUSE を使用して作成されたものの例をいくつか示します。
- mp3fs(FLAC ファイルを MP3 プレーヤーにコピー/クリックしてドラッグすると、その場で作成される MP3 ファイルとして表示されます)
- ピタグFS(メタデータ タグから構築された仮想フォルダーのツリーでメディアを表示します)
- ヒューズ-ジップ(Zipファイルをフォルダとしてマウント)
- ヒューズISO(ルート権限なしで ISO をマウントする)
- フューズ(iDevices をマウント)
- フューズDAV(WebDAV共有をマウント)
- ヒューズ-exfat(exFAT形式のファイルシステムをマウント)
- ntfs-3g(のLinux NTFS ドライバー)
B.キーボード、マウス、ジョイスティックなどの仮想入力デバイスを作成したい場合(例えば、使用しているUSBデバイス用のユーザースペースドライバーを作成する場合libusb
)、入力。
バインディングを見つけるのは難しいですが、行く(キーボードのみ)パイソン、 そしてルビー (2)。
実際の uinput の使用例は次のとおりです。
- G15デーモン(Logitech G15 ゲーミング キーボードの LCD とゲーミング キー用の Linux ドライバー)
- ds4drv(Sony DualShock 4 コントローラー用ドライバー)
- XboxDriver(代替XBox 360コントローラドライバとLinux相当の翻訳非常に設計の悪いゲームランナー2 未来リズム伝説 エイリアン実際のXboxコントローラーと話していると誤解されることがある)
- 古いWiimoteドライバはクウィドこれらは、最終的に誰かがカーネル Wiimote ドライバーを作成して、デフォルトでサポートが利用できるようになるまで必要でした。
C.一般的な文字デバイスの場合、キューズ(USErspace のキャラクタ デバイス) ただし、あまり人気がありません。
私が個人的に知っている CUSE API の唯一のユーザーは、その作成を促したプログラムと同じです。osspdは、、、および(OSS オーディオ API) をユーザー空間で実装し、PulseAudio または dmix を介してルーティングできるようにします/dev/dsp
。/dev/adsp
/dev/mixer
私が見つけることができた唯一のCUSEバインディングはキューピー2010 年以降更新されていません。
D.新しい特別なファイルはまったく必要ない場合もあります。
例えば、USBデバイスとの生の通信を次のように開くことができます。libusb(ページ上のバインディングのリスト)、その後、他のメカニズム (TCP/UDP ソケット、stdin/stdout またはディスク上の通常のファイルの読み取り/書き込みなど) を介して他のプログラムと通信します。