一个我无法修改的程序将其输出写入作为参数提供的文件中。我想让输出进入RAM,这样我就不必做不必要的磁盘IO。我想我可以使用tmpfs并"欺骗"程序来编写它,但并不是所有的Linux发行版都将tmpfs用于/tmp,有些在/run(Ubuntu)下安装tmpfs,有些在/dev/shm(RedHat)下安装。我希望我的程序尽可能地可移植,如果可以避免的话,我不想在用户的系统上创建tmpfs文件系统。显然,我可以执行df|grep-tmpfs并使用返回的任何装载,但我希望有更优雅的装载。是否可以写入伪终端或某个地方的/proc?
将/proc/self/fd/1
作为文件名传递给子程序。对/proc/self/fd/1
的所有写入实际上都将进入子程序的stdout。使用subprocess.Popen()
等捕获孩子的stdout。
如果子进程接受不可查找的文件,则可以尝试命名管道。命名管道的内容不接触磁盘。
您可以将Python脚本分为两部分,一部分重复调用另一个程序,另一部分合并结果,并将前者转换为Bash脚本,这样您就可以使用>()
进程替换构造将伪文件传递给另一个程序,该程序实际上是另一个进程的stdin。
PoC:
假设这是另一个程序:
$ cat otherprogram.py
#/usr/bin/env python
import sys
with open(sys.argv[1], 'w') as file:
file.write('Hellon')
它在参数中使用一个文件名,并向其写入"Hello"。假设您需要调用它五次。然后你可以做这样的事情:
for i in {1..5}; do python otherprogram.py >(cat) ; done
它将向stdout输出otherprogram.py
认为它正在写入文件的内容。然后,您可以将其与Python脚本的其他部分一起使用,如下所示:
$ cat consume.py
#!/bin/env python
import fileinput
for line in fileinput.input():
print "Processing line ", line
(这只是为"你好"做准备)
$ { for i in {1..5}; do python otherprogram.py >(cat) ; done } | python consume.py
Processing line Hello
Processing line Hello
Processing line Hello
Processing line Hello
Processing line Hello
因此,otherprogram.py
认为它在写入文件,实际上它是在发送到程序的stdin,而不会碰到磁盘,这要归功于Bash的进程子辅导机制。