python subprocess在执行时读取stdout

时间:2011-09-08 10:16:42

标签: python linux subprocess

我程序中的一个函数检查hashfile的md5sum

def check():
    print "checking integrity status.."
    md5 = subprocess.Popen(["md5sum", "-c", hashfile],shell=False, stdout=subprocess.PIPE)
    #fopen = open(basefile, "r")
    for f in md5.stdout.readlines():
        fc = f.rstrip("\n")
        sys.stdout.write("\rChecking..." + fc)
        sys.stdout.flush()

现在发生的事情是整个命令首先执行,然后使用md5.stdout.readlines从md5进行循环读取,因此它不是动态的,即我执行命令后不会得到输出....是有一种方法可以在命令执行时获得输出...

使用glglgl的答案修复:

def check():
    print "checking integrity status.."
    md5 = subprocess.Popen(["md5sum", "-c", hashfile],shell=False, stdout=subprocess.PIPE)
    #fopen = open(basefile, "r")
    fc = "NULL"
    i = 0
    for f in iter(md5.stdout.readline, ''):
        k = fc
        fc = f.rstrip("\n")
        if "FAILED" in fc:
            print fc
        i = i + 1
        sys.stdout.write("\rChecking... "+ str(i)+ " " + fc + (' ' * (len(k) - len(fc))) )
        sys.stdout.flush()

3 个答案:

答案 0 :(得分:5)

当然。有几种方法。

  1. 首先,您可以使用md5.stdout.read(),但在那里您必须自行进行分隔。

  2. 然后,您可以使用文件对象md5.stdout作为迭代器进行操作。但似乎存在缓冲问题,我。即你没有立即得到结果。

  3. 然后有可能反复拨打md5.stdout.readline(),直到它返回''

  4. 在这种情况下,第三种方式是首选;我建议这样做:

    ...

    for f in iter(md5.stdout.readline, ''):
        fc = f.rstrip("\n")
        sys.stdout.write("\rChecked " + fc)
        sys.stdout.flush()
    

    我也更改了输出文本,因为如果已经进行了che检查,只有一个输出。

    如果这不是您想要的,而是真正拥有单独捕获的每个输出,您应该切换到第1点。但这使它更复杂。我将考虑一个解决方案,表明它是需要的。

    在那里,必须考虑以下几点:

    • read()块,所以应该逐字节读取(非常难看)。
    • 有问题应该输出什么,何时应该有间歇输出。

答案 1 :(得分:1)

原始海报是正确的,在2.4版本中没有hashlib,但md5库是可用的。示例解决方法:

try:
        # Python 2.5 and up.
        import hashlib
        md5Hash = hashlib.md5

except ImportError:
        # Python 2.4 and below.
        import md5
        md5Hash = md5.new

somedata = 'foobar'
hashstring = md5Hash (somedata).hexdigest ()

答案 2 :(得分:0)

文件大小是多少?

Popen创建一个新的子进程来运行该命令。也许它在你运行for循环之前完成。

您可以检查“子流程”是否已完成查看返回码属性(在您的代码中:md5.returncode)