2

我正在处理从远程数据库中提取的数千个包装在类似 zip 文件容器中的二进制文件。我需要使用 readelf 之类的工具分析这些二进制文件的内容,但我想避免产生不必要的 IO 来将二进制文件写入磁盘。

有没有办法调用 subprocess.Popen 以便我可以将内存中的文件传递给命令行实用程序,该命令会将其理解为文件?我尝试将文件描述符分配给标准输入,但实用程序没有按预期从标准输入读取文件内容。

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])

我正在尝试的是可能的,还是我应该求助于写入磁盘并从那里分析?

非常感谢!

4

1 回答 1

1

Zeroth,你为什么需要popen readelf,而不是使用libelf或类似的东西?在 PyPI 上快速搜索“elf”显示了很多可能性。你看过他们吗?

首先,在许多平台上,所有的 I/O 最终都会通过缓存,所以它不会真正减慢你的速度,即使它最终最终将所有内容刷新到磁盘只是为了删除它(它可能永远不会做)。小心使用mmapcan 通常有助于避免刷新到磁盘,但您甚至可能不需要它。

所以说真的,我会先测试一下,看看过多的 I/O 是否真的会拖慢你的速度。如果没有,请停止担心。

如果您想确保没有磁盘 I/O(我假设您已禁用所有交换,否则这个想法一开始就毫无意义),最简单的解决方案是创建一个实际上不是的临时文件备份到磁盘。

最简单的方法是创建一个 ramdisk,然后将临时文件放在那里。

或者,大多数平台都有一种方法来创建一个临时文件,该文件要么从不备份到磁盘,要么仅在绝对必要时才备份到磁盘。不幸的是,我认为任何 stdlib Python 函数都不能做到这一点,在这种情况下,您必须为其编写特定于平台的代码。

如果您确实想将任意缓冲区作为标准输入传递给工具,这很容易。但是你必须知道如何告诉工具读取标准输入——这通常意味着像-c作为选项或-假文件名传递,或者有时只是不传递任何文件名。阅读手册页以查看哪个。例如:

with zipfile.ZipFile(file,'r') as z:
    with z.open(binary_path) as bin:
        subprocess.Popen(['gzip','-dc'], stdin=bin)

不幸的是,一些工具不能以这种方式工作,通常是因为它们需要一个可搜索的文件而不仅仅是一个流。我相信readelf是其中之一。所以这个选项不可用。

并且将任意 fd 传递给工具需要该工具有一种方法来获取任意 fd 而不是文件名,而大多数文件名都没有。

于 2012-12-12T19:58:01.790 回答