如何制作一个特殊文件,在从[重复]读取时执行代码

如何制作一个特殊文件,在从[重复]读取时执行代码

Linux系统上的大多数文件都是普通文件,即它们保存在磁盘上,读取它们只是从磁盘上指定的内存块中读取。我怎样才能制作一个行为类似于文件的东西,能够像普通文件一样读取它,但实际上返回以编程方式生成的数据?作为一个具体的例子,一个下载当前 google.com 并返回它的文件,这样cat ~/myspecialfile会将 google.com 的内容输出到 stdout?

答案1

正如其他答案所示,您可以使用命名管道完成您所要求的部分操作。对于完整的解决方案,您必须开发某种虚拟文件系统当访问虚拟文件系统上的路径时,它会执行所需的操作。有几种方法可以做到这一点:

  • 编写一个内核模式文件系统驱动程序,例如进程文件系统司机。
  • 编写一个用户模式文件系统实现,使用保险丝例如。
  • 编写一个程序,提供NFS服务器接口或其他网络文件系统协议。
  • 也许是一个假装是 USB 文件存储设备或其他硬件的程序。

答案2

可以想象,您可以使用 FIFO/命名管道执行类似的操作:

$ mkfifo ~/myspecialfile
$ wget -q -O ~/myspecialfile google.com &
[2] 26186
$ 

mkfifo创建一个名为 ~/myspecialfile 的命名管道。 wget然后将其输出定向到该命名管道。您可以从该命名管道中读取(一次),就像它是常规文件一样。例如,获取wc该文件的计数:

$ wc ~/myspecialfile
      7     430   17738 /home/ubuntu/myspecialfile
[2]+  Done                    wget -q -O ~/myspecialfile google.com
$ 

请注意,通常编写器(wget在本例中)将open()使用 O_WRONLY 标志的管道。此open()调用通常会阻塞,直到读取器(wc在本例中)使用 O_RDONLY 标志打开管道的另一端。因此,这里的wget进程将立即启动,但在读者(打开并)开始阅读之前,它不会在后台执行任何操作。我已在 Ubuntu 14.04 上使用wireshark 验证了此行为。

答案3

您可以创建myspecialfile一个命名管道。然后,您可以在后台运行一个脚本,该脚本循环将程序的输出写入管道:

#!/bin/bash
mkfifo ~/myspecialfile
while :; do
    run program here > ~/myspecialfile
done

这有一个限制。如果两个进程同时打开该文件,它们可能只能获得部分输出。

一种没有此限制的更复杂的方法是实现 FUSE 文件系统。~/myfyspecialfile将是文件系统的挂载点。

相关内容