我正在使用以下代码来运行另一个 python 脚本。我面临的问题是该脚本的输出以无序的方式出现。 从命令行运行它时,我得到正确的输出,即:
some output here
Editing xml file and saving changes
Uploading xml file back..
使用子进程运行脚本时,我以相反的顺序获取一些输出:
correct output till here
Uploading xml file back..
Editing xml file and saving changes
脚本正在执行,没有错误并进行了正确的更改。所以我认为罪魁祸首可能是调用子脚本的代码,但我找不到问题:
cmd = "child_script.py"
proc = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
(fout ,ferr) = ( proc.stdout, proc.stderr )
print "Going inside while - loop"
while True:
line = proc.stdout.readline()
print line
fo.write(line)
try :
err = ferr.readline()
fe.write(err)
except Exception, e:
pass
if not line:
pass
break
[编辑]:fo 和 fe 是输出和错误日志的文件句柄。此外,该脚本正在 Windows 上运行。很抱歉缺少这些详细信息。
最佳答案
恐怕您引用的脚本部分存在一些问题:
- 如 detly 中所述的评论,
fo
和fe
是什么?想必这些是您将子进程的输出写入其中的对象? (更新:您指出这些都是用于写入输出日志。) - 第 3 行存在缩进错误。(更新:我已在原始帖子中修复了该问题。)
- 您指定了
stderr=subprocess.STDOUT
,因此:(a)ferr
在循环中将始终为 None,并且 (b) 由于缓冲、标准输出并且错误可能会以不可预测的方式混合在一起。但是,从您的代码看来,您实际上想分别处理标准输出和标准错误,因此也许可以尝试使用stderr=subprocess.PIPE
来代替。
最好将循环重写为 jsbueno建议:
from subprocess import Popen, PIPE
proc = Popen(["child_script.py"], stdout=PIPE, stderr=PIPE)
fout, ferr = proc.stdout, proc.stderr
for line in fout:
print(line.rstrip())
fo.write(line)
for line in ferr:
fe.write(line)
...或者进一步减少它,因为看起来目标本质上只是想将子进程的标准输出和标准错误写入 fo
和 fe
,只需这样做:
proc = subprocess.Popen(["child_script.py"], stdout=fo, stderr=fe)
如果您仍然看到 fo
正在写入的文件中输出行被交换,那么我们只能假设有某种方式可以在子脚本中发生这种情况。例如子脚本是多线程的吗?其中一行是通过另一个函数的回调打印的吗?
关于python - 从子进程运行的子进程的乱序输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5139795/