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/tcp
bash shell 是一个具有和实现的程序/dev/udp
(复制自ksh93
)。当您尝试使用 bash 重定向运算符打开路径时,它将不会执行普通的open
系统调用。相反,bash 将创建一个 TCP 套接字并将其连接到指定的端口。
这是在用户模式下实现的,并且仅在某些程序中实现,如以下示例所示,该示例演示了 letbash
和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
,它bash
只会使用重定向运算符进行 TCP 连接,而不会在其他可能打开文件(如source
或.
内置)的地方进行。
答案3
答案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 或磁盘上的常规文件等)与其他程序进行通信。