Python popen不适用于块设备

时间:2009-12-06 19:42:21

标签: python pipe subprocess

到目前为止,我正在使用一个小型的取证应用

import time, os,sys

def getter():
    filename = sys.argv[1]
    print "File Entered: " + filename
    os.system('file ' + filename)
    print "\n"
    pipe =  os.popen("xxd " + filename, "r")
    print pipe.read()

我通过命令行输入一个文件并打印出文件类型,然后它应该创建一个从终端回到管道名称“pipe”下的python应用程序的管道。然后我读了名为“pipe”的管道

这适用于较小的文本文件,但即使我以超级用户身份运行此应用程序,它也无法在块设备上运行。最后,这将根据xxd的输出恢复文件。

任何提示,谢谢。

3 个答案:

答案 0 :(得分:4)

我假设你已经从shell提示符中尝试了相同的命令,并且它运行良好,即使是通过管道传输到less或类似的东西。

我强烈感觉使用subprocess会解决此问题;该模块取代了不推荐使用的popen调用,并在运行和获取执行命令的结果方面提供了很大的灵活性。

output = Popen(["xxd", "file"], stdout=PIPE).communicate()[0]

尝试在自己的shell下运行该进程,并读取其管道。如果这仍然不起作用,请确保为其缓冲区大小设置合理的限制,并确保您没有使用communicate,这将使您等到进程终止(处理块设备很长一段时间) )。

评论我的答案,如果它不起作用,并试着准确地描述什么是错误的 - 它是冻结的,只是没有输出或腐败的结果?

答案 1 :(得分:3)

如果您只是从shell提示符运行xxd /dev/diskwhatever会发生什么?它有用吗,它有多少信息?假设作为超级用户,您确实具有读取权限,那么尝试在代码的最后一行读取所有内容将是可以预期失败的点(因为信息量可能非常大);解决方法是一次阅读一点,而不是进行一次.read()调用。

修改:是否以现代的方式(使用subprocess)或不推荐使用的旧方法(使用popen)获取管道,对这个问题没有任何影响。在任何一种情况下,只需循环管道对象就可以一次获得一行,例如:

child = subprocess.Popen(whatever, stdout=subprocess.PIPE)
for line in child.stdout:
  print "One more line:", line

答案 2 :(得分:1)

问题可能在于您如何调用xxd,因为您的应用程序根本不对该文件执行任何操作。