12

在 Linux 中创建“虚拟”文件的最直接方法是什么,允许对其进行读取操作,始终返回某些特定命令的输出(每次读取文件时运行)?因此,每个读取操作都会导致执行命令,捕获其输出并将其作为文件的“内容”传递。

4

4 回答 4

7

没有办法创建这种所谓的“虚拟文件”。另一方面,您可以通过 FUSE 在用户空间中实现简单的合成文件系统来实现此行为。此外,您不必使用 c,甚至对于脚本语言(如 python)也有绑定。

编辑:很有可能这样的东西已经存在:例如参见scriptfs

于 2014-08-31T22:57:41.193 回答
4

这是我在下面复制的一个很好的答案。

基本上,命名管道让您可以在脚本中执行此操作,而Fuse让您可以在Python中轻松执行此操作。


您可能正在寻找命名管道

mkfifo f
{
  echo 'V cebqhpr bhgchg.'
  sleep 2
  echo 'Urer vf zber bhgchg.'
} >f
rot13 < f

写入管道不会启动监听程序。如果要循环处理输入,则需要保持监听程序运行。

while true; do rot13 <f >decoded-output-$(date +%s.%N); done

请注意,写入管道的所有数据都会合并,即使有多个进程写入也是如此。如果多个进程正在读取,则只有一个进程获取数据。所以管道可能不适合并发情况。

命名套接字可以处理并发连接,但这超出了基本 shell 脚本的能力。

规模最复杂的一端是自定义文件系统,它允许您设计和安装一个文件系统,其中每个open,write等都触发程序中的一个函数。最少的投资是几十行非平凡的编码,例如在Python中。如果只想在读取文件时执行命令,可以使用scriptfsfuseflt

于 2015-04-24T04:41:11.860 回答
2

没有人提到这一点,但如果您可以选择文件的路径,则可以使用标准输入/dev/stdin

每次cat程序运行时,它最终都会读取程序的输出写入管道,这只是echo my input在这里:

for i in 1 2 3; do
    echo my input | cat /dev/stdin
done

输出:

my input
my input
my input
于 2014-08-31T23:13:21.757 回答
2

恐怕这不容易。当一个进程从一个文件中读取数据时,它会使用系统调用,如open, fstat, read. 您需要拦截这些调用并输出与它们返回的不同的内容。这将需要编写某种内核模块,即使那样它也可能被证明是不可能的。

但是,如果您只需要在访问某个文件时触发某些东西,您可以使用inotifywait

#!/bin/bash

while inotifywait -qq -e access /path/to/file; do
        echo "$(date +%s)" >> /tmp/access.txt
done

将其作为后台进程运行,/tmp/access.txt每次读取文件时都会获得一个条目。

于 2014-08-31T22:32:03.393 回答