在 Linux 中创建“虚拟”文件的最直接方法是什么,允许对其进行读取操作,始终返回某些特定命令的输出(每次读取文件时运行)?因此,每个读取操作都会导致执行命令,捕获其输出并将其作为文件的“内容”传递。
4 回答
没有办法创建这种所谓的“虚拟文件”。另一方面,您可以通过 FUSE 在用户空间中实现简单的合成文件系统来实现此行为。此外,您不必使用 c,甚至对于脚本语言(如 python)也有绑定。
编辑:很有可能这样的东西已经存在:例如参见scriptfs。
这是我在下面复制的一个很好的答案。
基本上,命名管道让您可以在脚本中执行此操作,而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中。如果只想在读取文件时执行命令,可以使用scriptfs或fuseflt。
没有人提到这一点,但如果您可以选择文件的路径,则可以使用标准输入/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
恐怕这不容易。当一个进程从一个文件中读取数据时,它会使用系统调用,如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
每次读取文件时都会获得一个条目。