我正在使用以下代码运行另一个python脚本。我面临的问题是,该脚本的输出是以一种无序的方式出现的。
从命令行运行时,我得到正确的输出,即:
这里有些输出
编辑xml文件并保存更改
正在将xml文件上载回。。
在使用subprocess运行脚本时,我以相反的顺序获取一些输出:
正确输出到这里
正在将xml文件上载回。。
编辑xml文件并保存更改
脚本正在无错误地执行并进行正确的更改。所以我认为罪魁祸首可能是调用子脚本的代码,但我找不到问题所在:

    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评论中提到的,什么是fofe?假设这些对象是编写子进程输出的对象?(更新:您指示这两个都用于写入输出日志。)
第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)

... 或者进一步减少它,因为目标似乎本质上是您只想将标准输出和标准错误从子进程写入fofe,只需:
proc = subprocess.Popen(["child_script.py"], stdout=fo, stderr=fe)

如果您仍然看到fo正在写入的文件中交换的输出行,那么我们只能假设在子脚本中有某种方式可以发生这种情况。子脚本是多线程的吗?其中一行是通过另一个函数的回调打印的吗?

10-08 01:16