【问题标题】:Subprocess hangs / delayed with popen communicate() or wait() (Python 2.7.9)子进程挂起/延迟与 popencommunicate() 或 wait() (Python 2.7.9)
【发布时间】:2015-05-29 11:50:51
【问题描述】:

经过很多不同的测试,搜索并尝试了其他人的不同方法,我现在有点迷路了,所以希望任何人都可以帮助我......

我正在尝试生成子进程(在我的情况下调用外部 powershell 脚本),我想获取标准输出和返回码。 过去,我的代码已经在 win32 下使用旧版本的 Python 2.7 运行,但现在在我的新开发机器(64Bit/Win7)上我无法让它完全运行...... :-/(我认为我的旧机器是 32Bit,如果这可能是个问题)

奇怪的是:在我的 Eclipse 环境 (4.4.1) 中执行代码基本上可以工作,但它只是在标准输出行之后“挂起”。输出在调用proc.communicate() 的点“DEBUG1”之前“延迟”(proc.wait() 也是如此)。 (我没有看到 'DEBUG1' 或 'DEBUG2' 但我看到了 'DEBUG0' 和 logger.info(stdout) 行)

更详细地解释这一点: 如果我只是等待一段时间,在“DEBUG0”和标准输出行之后什么都不会发生。 但是 - 如果我按下“回车”,然后输出恢复,我看到“DEBUG1”,然后大约一秒钟后“突然”子进程完成,所有输出都给出(也有“DEBUG2”)一切都很好......(就像以前一样)

我只是不明白当我不在那里按 Enter 键时如何自动解决此问题...:-/

正如我所说,该代码过去已经在我的旧开发环境中工作,当然没有点击“输入”;)认为也许 flushing 会有所帮助,但这并没有作为你可以看到。

有什么想法吗?提示?非常感谢!

这里是决定代码sn-p:

    try:
        proc = subprocess.Popen([powershell_bin,
                               '-ExecutionPolicy',
                               'Unrestricted',
                               '-NonInteractive',
                               '-NoProfile',
                               '-Command',
                               settings['ext_ps_commands'][self.cmd],
                               usr,
                               grp],
                               stdout=subprocess.PIPE)
    except Exception as e:
        warnmsg = "..."
        logger.warn(warnmsg)
        return -1

    print "DEBUG0"
    sys.stdout.flush()

    while True:
        line = proc.stdout.readline()
        if line != '':
            stdout = "  stdout:", line.rstrip()
            logger.info(stdout)
        else:
            break

    print "DEBUG1"
    sys.stdout.flush()

    exitcode = proc.wait()
    # stdout, stderr = proc.communicate()
    # exitcode = proc.returncode

    print "DEBUG2"
    sys.stdout.flush()

    return exitcode

【问题讨论】:

  • 不相关:不要使用裸露的except:(例如,您通常不想抓住KeyboardInterrupt);你可以改用except Exception as e: logger.error(...)。如果您从控制台(cmd.exe)而不是 Eclipse 运行 Python 脚本,它会挂起吗?你试过设置stdin=open(os.devnull, 'rb', 0)吗?你可以use for line in iter(proc.stdout.readline, b''): instead of the while-loop

标签: eclipse windows python-2.7 subprocess pywin32


【解决方案1】:

@J.F.塞巴斯蒂安: 非常感谢您的想法和建议(包括改进的异常处理),实际上您带来了解决方案:这是一个 Eclipse/PyDev 问题。 在原始的cmd.exe 控制台中,代码工作得很好! :) (.communicate().wait() 的两个版本)

这是我第一次遇到控制台和 Eclipse 之间的行为差​​异,所以我只是没有想到这一点。似乎我的 Eclipse 中存在一些错误或配置问题。是 Eclipse SDK Luna SR1 (4.4.1) 和 PyDev 3.9.1,可能我应该测试 Eclipse 4.4.2 和 PyDev 3.9.2。

再次感谢!

【讨论】:

    猜你喜欢
    • 2017-02-28
    • 1970-01-01
    • 2012-09-07
    • 2015-07-07
    • 1970-01-01
    • 2016-03-29
    • 2013-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多