4

假设我有一个很大的 gzip 文件data.txt.gz,但通常需要将未压缩的版本提供给程序。当然,data.txt可以使用进程替换语法,而不是创建一个独立的 unpacked :

./program <(zcat data.txt.gz)

但是,根据具体情况,这可能令人厌烦且容易出错。

有没有办法模拟命名进程替换?也就是说,创建一个伪文件data.txt,该文件在被访问时会“展开”为进程替换zcat data.txt.gz。与符号链接将读取操作转发到另一个文件不同,但在这种情况下,它需要是一个临时命名管道。

谢谢。

PS。有点类似的问题


编辑(来自评论)实际用例有一个大型 gzip 语料库,除了以原始形式使用外,有时还需要使用一系列轻量级操作(标记化、小写等)进行处理,然后馈送到一些“更重”的代码。存储经过预处理的副本会浪费磁盘空间,并且重复重新键入完整的预处理管道可能会引入错误。同时,动态运行管道会产生很小的计算开销,因此需要一个长期存在的伪文件来隐藏细节。

4

2 回答 2

5

据我所知,您所描述的内容并不存在,尽管这是一个有趣的想法。它需要内核支持,以便打开文件实际上会运行任意命令或脚本。

最好的办法是将长命令保存到 shell 函数或脚本中,以降低调用进程替换的难度。

于 2014-06-05T13:30:37.357 回答
0

有多种选择,取决于您需要什么以及您愿意付出多少努力。

如果您需要一个一次性文件,您可以使用它mkfifo来创建文件,启动将存档重定向到 fifo,并将 fifo 的文件名传递给需要从中读取的任何人。

如果您需要重复访问该文件(可能同时),您可以使用 netcat 设置一个套接字,一遍又一遍地为解压缩的文件提供服务。

使用“传统的 netcat”,这就像while true; do nc -l -p 1234 -c "zcat myfile.tar.gz"; done. 使用 BSD netcat 有点烦人:

# Make a dummy FIFO
mkfifo foo

# Use the FIFO to track new connections
while true; do cat foo | zcat myfile.tar.gz | nc -l 127.0.0.1 1234 > foo; done

无论如何,一旦服务器(或基于文件的域套接字)启动,您只需nc localhost 1234读取解压缩文件即可。您当然可以在nc localhost 1234其他地方用作流程替换的一部分。

它看起来像这样(图像可能最好在单独的选项卡中查看):

netcat 服务器演示

根据您的需要,您可能希望使 bash 脚本更复杂,以用于缓存等,或者只是转储此内容并使用您熟悉的某种脚本语言使用常规 Web 服务器。

最后,这可能是最“异国情调”的解决方案,您可以编写一个 FUSE 文件系统,该文件系统呈现由您内心所需的任何逻辑支持的虚拟文件。在这一点上,您可能应该仔细考虑一下您要去的地方的可维护性和复杂性成本是否真的抵消了不得不zcat额外调用几次的人。

于 2018-03-01T00:55:54.933 回答