【问题标题】:Python popen wont work with block devicesPython popen 不适用于块设备
【发布时间】:2009-12-06 19:42:21
【问题描述】:

我正在编写一个到目前为止看起来像这样的小型取证应用程序

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 应用程序的管道。然后我阅读了名为“管道”的管道

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

任何提示,谢谢。

【问题讨论】:

  • popen 已弃用。请改用subprocess 模块。
  • Deprecated 意味着现在有更好的方法来执行相同的任务,并且在将来的某个时间点将从语言中删除不推荐使用的方法。

标签: python pipe subprocess


【解决方案1】:

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

我有一种强烈的感觉,使用subprocess 可以解决这个问题;该模块取代了已弃用的 popen 调用,并在运行和从执行的命令中获取结果方面提供了极大的灵活性。

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

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

如果我的答案不起作用,请评论我的答案,并尝试准确描述没有错的地方 - 是冻结、没有输出还是损坏的结果?

【讨论】:

  • 我可以使用什么来一次提取一行数据,而不是进行通信?这就是我目前所拥有的“pipe = subprocess.Popen(["xxd",filename], stdout=subprocess.PIPE)"
  • @Recursion,我刚刚编辑了我的答案以表明这一点——归结为for line in pipe.stdout:
【解决方案2】:

如果您只是在 shell 提示符下运行 xxd /dev/diskwhatever 会发生什么?它是否有效,它会喷出多少信息?假设,作为超级用户,您确实具有读取权限,那么尝试在代码的最后一行中一口气读取所有内容可能会导致失败(因为信息量可能非常巨大);解决方法是一次读一点,而不是打一个 .read() 电话。

编辑:无论您以现代方式(subprocess)还是已弃用但仍在工作的旧方式(popen)获得管道,都没有区别这个问题。无论哪种情况,您都可以通过遍历管道对象一次获取一行,例如:

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

【讨论】:

  • 就是这样。试试 print pipe.read(1) 你可能会得到一些数据。
【解决方案3】:

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

【讨论】:

  • ...除非您的问题实际上是使用 popen 给您的管道对象。
  • 当我在终端中运行它时,它工作正常。它也适用于小文本文件。
猜你喜欢
  • 2014-11-25
  • 2012-01-08
  • 1970-01-01
  • 2015-05-10
  • 2012-10-05
  • 1970-01-01
  • 1970-01-01
  • 2016-10-11
  • 1970-01-01
相关资源
最近更新 更多