“/dev”Linux 文件是如何创建的?

“/dev”Linux 文件是如何创建的?

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”告诉你这是一个“字符设备”;另一种类型是“块设备”(打印为ls“b”)。粗略地说,像硬盘这样的随机访问设备往往是块设备,而像磁带驱动器或声卡这样的顺序设备往往是字符设备。

“1、5”部分是“主设备号”和“次设备号”。

有了这些信息,我们就可以使用mknod命令来制作我们自己的设备节点:

# mknod foobar c 1 5

这会在当前文件夹中创建一个名为 的新文件foobar,该文件的作用是确切地与 相同的事情/dev/zero。 (当然,如果您愿意,您可以为其设置不同的权限。)这个“文件”真正包含的就是上面的三项——设备类型、主设备号、次设备号。您可以用来ls查找其他设备的代码并重新创建这些代码。当你感到无聊时,只需使用rm删除刚刚创建的设备节点即可。

基本上,主设备号告诉 Linux 内核要与哪个设备驱动程序通信,次设备号告诉设备驱动程序您正在谈论哪个设备。 (例如,您可能有一个 SATA 控制器,但可能插入了多个硬盘。)

如果你想发明做新事情的新设备...好吧,您需要编辑 Linux 内核的源代码并编译您自己的自定义内核。所以我们不要这样做! :-) 但是您可以添加与您已有的设备文件重复的设备文件。像 udev 这样的自动化系统基本上只是监视设备事件并自动为您调用mknod/ 。rm没有什么比这更神奇的了。

仍然有其他特殊文件种类:

  • Linux 认为目录是一种特殊的文件。 (通常你不能直接打开一个目录,但如果可以的话,你会发现它是一个普通文件,包含特殊格式的数据,并告诉内核在哪里可以找到该目录中的所有文件。)

  • 符号链接是一个特殊的文件。 (但硬链接不是。)您可以使用该ln -s命令创建符号链接。 (查找它的联机帮助页。)

  • 还有一种称为“命名管道”或“FIFO”(先进先出队列)的东西。您可以使用 来创建一个mkfifo。 FIFO 是一个神奇的文件,可以通过以下方式打开一次编程——一次阅读,一次写作。当这种情况发生时,它的工作方式就像普通的外壳管道一样。但你可以单独启动每个程序......

无论如何都不“特殊”的文件称为“常规文件”。您偶尔会在 Unix 文档中看到对此的提及。这就是它的意思;不是设备节点或符号链接或其他任何内容的文件。只是一个普通的日常文件,没有任何神奇的属性。

答案2

大多数/dev条目是块设备 inode 或字符设备 inode。维基百科有很多细节关于这一点,我不再重复。

但是/dev/tcp您的问题中提到的任何现有答案都没有解释。/dev/tcp并且/dev/udp与大多数其他条目不同/dev。块设备和字符设备是由内核实现的,而/dev/tcp/dev/udp是在用户模式下实现的。

/dev/tcpbash shell 是一个具有和实现的程序/dev/udp(复制自ksh93)。当您尝试使用 bash 重定向运算符打开路径时,它将不会执行普通的open系统调用。相反,bash 将创建一个 TCP 套接字并将其连接到指定的端口。

这是在用户模式下实现的,并且仅在某些程序中实现,如以下示例所示,该示例演示了 letbashcattry 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,它bash只会使用重定向运算符进行 TCP 连接,而不会在其他可能打开文件(如source.内置)的地方进行。

答案3

除了其他答案中解释的设备节点(使用麦克诺德(2)或由某些提供开发文件系统),Linux还有专门提供的其他“神奇”文件虚拟文件系统,特别是在/proc/(参见过程(5), 阅读进程文件系统)和/sys/(阅读有关系统文件系统)。

这些伪文件(看起来 -eg统计数据(2)- 作为普通文件,而不是设备)是内核提供的虚拟视图;特别是,从/proc/(例如 withcat /proc/$$/maps或 by打开(2)-ing/proc/self/status在你的程序中)通常不涉及来自磁盘或网络的任何物理 I/O,因此速度相当快。

要创建一些额外的伪文件,/proc/通常应该编写自己的伪文件内核模块并加载它(参见例如)。

答案4

正如其他用户已经详细解释的那样,特殊文件需要代码来备份它们。然而,似乎没有人提到 Linux 提供了几种在用户空间编写代码的方法:

A。 保险丝(USERspace 中的文件系统)允许您编写类似的内容,/proc而不会导致内核崩溃,并以您选择的语言/运行时来完成,例如,Node.js,珀尔,PHP,Python, 红宝石,,ETC。

它还具有无需安装 FUSE 文件系统的优点,sudo因为它们以用户执行安装的方式运行。

以下是人们使用 FUSE 编写的一些示例:

  • mp3fs(将 FLAC 文件查看为 MP3 文件,当您将它们复制/单击并拖动到 MP3 播放器时,这些文件会即时创建)
  • PyTagsFS(在根据元数据标签构建的虚拟文件夹树中查看您的媒体)
  • 保险丝拉链(将 Zip 文件安装为文件夹)
  • 保险丝ISO(无需root权限即可挂载ISO)
  • 保险丝(安装 i 设备)
  • 熔断器DAV(挂载WebDAV共享)
  • 保险丝-exfat(挂载 exFAT 格式的文件系统)
  • NTFS-3G(Linux NTFS 驱动程序)

B.如果你想创建一个虚拟输入设备,如键盘、鼠标、操纵杆等(例如,为你正在使用的 USB 设备编写用户空间驱动程序libusb),可以使用输入法

它的绑定很难找到,但我知道它们存在的目的(仅限键盘),Python, 和红宝石 (2)

现实世界中 uinput 使用的示例包括:

  • G15守护进程(Logitech G15 游戏键盘上的 LCD 和游戏按键的 Linux 驱动程序)
  • ds4drv(Sony DualShock 4 控制器的驱动程序)
  • xbox驱动(替代 Xbox 360 控制器驱动程序和 Linux 相当于x360ce设计得很糟糕的游戏,比如亚军2:未来节奏异形传奇可以认为他们正在与真正的 Xbox 控制器对话,但实际上并非如此)
  • Wiimote 老司机喜欢西维德在有人最终编写内核 Wiimote 驱动程序之前需要这样做,因此默认情况下会提供支持。

C。对于通用字符设备,有库塞(USERspace 中的字符设备)。但它不太受欢迎。

据我个人所知,CUSE API 的唯一用户是促使其创建的同一程序:奥斯普德,它在用户空间中实现/dev/dsp/dev/adsp/dev/mixer(OSS 音频 API),以便它们可以通过 PulseAudio 或 dmix 进行路由。

我能找到的唯一 CUSE 绑定是库塞皮,自 2010 年以来就没有更新过。

D .您可能根本不需要新的特殊文件。

例如,您可以使用以下命令打开与任何 USB 设备的原始通信libusb(页面上的绑定列表),然后通过其他一些机制(TCP/UDP 套接字、读/写 stdin/stdout 或磁盘上的常规文件等)与其他程序进行通信。

相关内容