【问题标题】:Weird IO behavior with subprocess子进程的奇怪 IO 行为
【发布时间】:2013-03-15 15:45:58
【问题描述】:

我在 python 中注意到这种奇怪的行为——我试图记录一个进程的输出,然后读取这个输出并对其进行一些处理。即使在程序运行后打开文件时文件包含所有文本,但我无法读取任何内容。

就这么简单

f=open("blah.txt",'w')
#I log the output of a program with subprocess
Cmdline="program.exe"
Dump= subprocess.Popen(CmdLine,stdout=f,stderr=subprocess.STDOUT)
#Waiting for it to finish
while(Dump.poll() is not None): #returns None while subprocess is running
        print "waiting on process to finish \n"
f.flush() #I flush everything to make sure it was written
sys.stdout.flush()
f.close()
#now i need to read from this file

f= open("blah.txt", 'r')
line=f.readline()
while line:
    print line
    line=f.readline()

f.close()

我什么也没读,但是当我在运行程序后打开文件 blah.txt 时,一切都在那里。关于我可能做错了什么的任何提示?我根本没有从“等待过程完成”中得到任何打印,但该过程大约需要一秒钟才能运行。

【问题讨论】:

  • 什么是f?不应该是f = open(...吗?
  • 对不起,错字。固定的。这不是我程序中的问题。
  • @Illusionist 有很多地方很明显这不是您正在运行的程序。请发布actual program 并尽可能少修改 - 否则,错误可能在其他地方。例如,this demo program 在我的系统上运行良好。
  • 最小化您的应用程序,但确保它仍然会重现问题。发布它。
  • 你几乎不想像那样循环poll。如果您想阻止直到完成,只需致电wait。如果你真的因为某种原因必须忙着等待,至少sleep 每次通过循环,而不是试图消耗尽可能多的 CPU 时间,你可以什么都不做。

标签: python subprocess stdout


【解决方案1】:

您的代码中的错误是这部分

while(Dump.poll() is not None): # While dump.pool is not None keep the loop going

应该是

while(Dump.poll() is None): # While dump.pool is None keep the loop going

在您的 while 循环中,只要Dump.poll() 不是无,您就基本上保持循环继续进行。问题是 Dump.pool() 在进程完成之前返回 None 。这意味着 while 循环将被立即取消,然后您才能捕获进程的任何输出。

这是您的代码的更新版本,我确认它可以按预期工作。

with open("blah.txt",'w') as w:
    #I log the output of a program with subprocess
    Cmdline="program.exe"
    Dump = subprocess.Popen(CmdLine,stdout=w,stderr=subprocess.STDOUT)
    #Waiting for it to finish
    while(Dump.poll() is None): #returns None while subprocess is running
        print "waiting on process to finish \n"
    w.flush() #I flush everything to make sure it was written
    sys.stdout.flush()

#now i need to read from this file
with open("blah.txt", 'r') as f:
    line=f.readline()
    while line:
        print line
        line=f.readline()

我还建议您使用with 关键字来确保文件在完成任务后始终正确关闭。

【讨论】:

  • a with - 语句会在套件完成后自动关闭您的文件,因此不需要 w.close()f.close()
  • @ferkulat 啊,粘贴代码时忘记编辑了。 ;)
【解决方案2】:

等到您的转储过程完成:

Dump= subprocess.Popen(CmdLine,stdout=f,stderr=subprocess.STDOUT)
#Waiting for it to finish
Dump.wait() # or -> while(Dump.poll() is None): print...

发生的情况是,由于您的等待循环是错误的,因此您不会在轮询之前对进程进行更改以启动,因此它甚至不会在关闭/打开文件之前等待它启动:

【讨论】:

  • +1 不错,但除非我误解了他,否则他提到该文件确实包含所有预期的文本,只是没有出现在第二部分中。
  • 是的,但它会在执行读取打开位后填充
  • 顺便说一句,他的代码有问题,否则是一个错字。 while 循环应该是is None,而不是is not None
猜你喜欢
  • 2021-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-15
相关资源
最近更新 更多