模拟“命名”流程替换

问题描述 投票:4回答:2

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

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

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

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

谢谢。

PS。 Somewhat similar question


Edit (from comments) The actual use-case is having a large gzipped corpus that, besides its usage in its raw form, also sometimes needs to be processed with a series of lightweight operations (tokenized, lowercased, etc.) and then fed to some "heavier" code. Storing a preprocessed copy wastes disk space and repeated retyping the full preprocessing pipeline can introduce errors. In the same time, running the pipeline on-the-fly incurs a tiny computational overhead, hence the idea of a long-lived pseudo-file that hides the details under the hood.
bash unix named-pipes process-substitution
2个回答
5
投票

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

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


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作为其他地方的流程替换的一部分。

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

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

最后,这可能是最“异国情调”的解决方案,您可以编写一个FUSE文件系统,该系统提供虚拟文件,支持您心中所需的任何逻辑。在这一点上,你可能应该很好地思考一下你去哪里的可维护性和复杂性成本是否真的抵消了不得不再多次调用zcat的人。

© www.soinside.com 2019 - 2024. All rights reserved.