模拟“命名”流程替换

时间:2014-06-05 12:43:09

标签: bash unix named-pipes process-substitution

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

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

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

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

感谢。

PS。 Somewhat similar question

<小时/> 编辑(来自评论)实际的用例是拥有一个大型的gzip语料库,除了以原始形式使用外,还有时需要使用一系列轻量级操作进行处理(标记化,小写,等)然后喂给一些重的&#34;码。存储预处理的副本会浪费磁盘空间并重复重新输入完​​整的预处理管道可能会引入错误。同时,在运行中运行管道会产生很小的计算开销,因此需要一个长期存在的伪文件来隐藏详细信息。

2 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分: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 server demo

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

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