我正在处理数千个二进制文件,这些二进制文件封装在类似zip的文件容器中,从远程数据库中提取。我需要使用readelf等工具来分析这些二进制文件的内容,但我希望避免在将二进制文件写入磁盘时产生不必要的IO。
是否有调用子流程的方法。Popen,这样我就可以将内存中的文件传递给命令行实用程序,该命令将其理解为一个文件?我已经尝试将文件描述符分配给stdin,但实用程序没有按预期从stdin读取文件内容。
with zipfile.ZipFile(file,'r') as z:
with z.open(binary_path) as bin:
subprocess.Popen(['readelf','-d'],stdin=bin)
我还尝试过直接将必要的参数设置为对文件描述符的引用,但这也被证明是徒劳的:
with zipfile.ZipFile(file,'r') as z:
with z.open(binary_path) as bin:
subprocess.Popen(['readelf','-d',bin])
我正在尝试的是可能的吗?还是应该直接写入磁盘并从中进行分析?
非常感谢!
Zeroth,为什么需要popen
readelf
,而不是使用libelf
或类似的东西?在PyPI快速搜索"elf"显示了很多可能性。你看过了吗?
首先,在许多平台上,所有的I/O最终都会通过缓存,所以它不会真正减慢速度,即使它最终将所有内容都刷新到磁盘上只是为了删除它(它可能永远不会这样做)。仔细使用mmap
通常有助于避免刷新磁盘,但您可能根本不需要它
所以说真的,我会先测试一下,看看过多的I/O是否真的会让你慢下来。如果没有,就别担心了。
如果你想确保没有磁盘I/O(我假设你已经禁用了所有交换,因为否则这个想法一开始就没有意义),最简单的解决方案是创建一个实际上没有备份到磁盘的临时文件。
最简单的方法是创建一个ramdisk,并将临时文件放在那里。
或者,大多数平台都有一种方法来创建一个临时文件,该文件要么从未备份到磁盘,要么只有在绝对必要时才备份到磁盘。不幸的是,我认为任何stdlibPython函数都不能做到这一点,在这种情况下,您必须为它编写特定于平台的代码
如果您确实想将任意缓冲区作为stdin传递给工具,这很容易。但您必须知道如何告诉工具读取stdin——这通常意味着将-c
作为选项或将-
作为假文件名传递,或者有时只是不传递任何文件名。阅读手册页,看看是哪一个。例如:
with zipfile.ZipFile(file,'r') as z:
with z.open(binary_path) as bin:
subprocess.Popen(['gzip','-dc'], stdin=bin)
不幸的是,有些工具不能以这种方式工作,通常是因为它们需要一个可查找的文件,而不仅仅是一个流。我相信readelf
就是其中之一。因此,此选项不可用。
将任意fd传递给工具需要该工具有一种方法来获取任意fd,而不是文件名,而大多数文件名都没有。