Python子流程完成,但输出文件不可用

时间:2014-04-14 18:56:57

标签: python subprocess

我的python代码使用子进程来调用" ifconfig"通过shell并使用">"将输出写入文本文件。当子进程完成并返回成功时,我读取输出文件。我是以固定的间隔执行此操作来监控网络状态,但有时我无法打开输出文件。我刚刚读到Popen有stdout和stderr的可选参数,这可能更安全/更好地支持,但我很好奇我的当前版本失败的原因。我的代码如下。我的库中有一些对象和宏没有解释,但我认为这个问题的代码仍然足够清晰。

为什么打开输出文件偶尔会失败?子进程返回时,文件是否可能未就绪?什么是保证它准备好开放的方式?

       # Build command line expression.
        expr = 'ifconfig' + ' >' + outputFile + ' 2>&1'

        try:
            # Execute command line expression.
            p = subprocess.Popen(expr, shell=True)
        except:
            Error("Unable to open subprocess.")

        if(p is None):
            Error("Unable to create subprocess.")

        # Wait until command line expression has been executed.
        wait = Wait.Wait(Constants.MIN_TIME_TO_QUERY_NETWORK_INFO, Constants.MAX_TIME_TO_QUERY_NETWORK_INFO)

        #Execute command then wait for timeout.    
        if (wait.StopUntilCondition(operator.ne, (p.poll,), None, True)):
            p.kill()
            Error("Get subnet mask subprocess timed out.")

        if(not p.poll() == 0):
            Error("Failed to get network information from operating system.")

        Warning("About to read output file from get subnet mask...")

        # Read temporary output file.
        f = open(outputFile, "r")
        networkInfo = f.read()
        f.close()

2 个答案:

答案 0 :(得分:2)

为避免输出损坏/丢失,您应该在尝试读取文件之前调用p.wait()。在这种情况下,您不需要使用文件:

from subprocess import check_output, STDOUT

network_info = check_output('ifconfig', stderr=STDOUT)

如果要在完成之前中断ifconfig读取其输出;见Stop reading process output in Python without hang?

答案 1 :(得分:0)

使用subprocess.Popen()并将该输出自己写入文件可能更容易。请注意,如果要捕获stdout和stderr,则无法使用subprocess.check_output

try:
    p = subprocess.Popen(['ifconfig'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    outdata, errdata = p.communicate()
except Exception as e:
    print "An error occurred:", e
with open(outputFile, 'w') as outf:
    outf.write(outdata)

有了这个,你不必等待; communicate在流程结束前不会返回。

如果您只想捕获标准输出,请改用subprocess.check_output;

try:
    outdata = subprocess.check_output(['ifconfig'])
except Exception as e:
    print "An error occurred:", e
with open(outputFile, 'w') as outf:
    outf.write(outdata)