如何在使用os.execl替换进程时重定向stdin / stdout / stderr

时间:2017-12-17 00:05:23

标签: python pycharm os.execl

请考虑以下示例脚本:

import os
import sys

print(1)
os.execl(sys.executable, sys.executable, '-c', 'print(2)')
print(3)

结果是

1

我在期待

1
2

我认为这是因为替换过程没有使用相同的stdin / stdout / stderr?

如何在使用execl时实现我的期望?

我在Windows上使用Python 3.6。

2 个答案:

答案 0 :(得分:2)

这不是关于PyCharm的错误,因为我无法用IDEA重现它。 IDEA正在使用与PyCharm相同的核心。

这是因为您启动脚本的方式。如果您使用Run启动脚本,则可以正常运行。如果您使用Debug启动它,则不会。

因为Run只是在终端中运行脚本,但Debug将启动调试器并将该进程连接到此调试器。您看到的输出实际上来自调试器,但不是直接来自您的脚本。替换进程时,调试器不会重建与新创建进程的连接。

这就是你没有输出2的原因。

答案 1 :(得分:1)

在Linux中,有一个标记FD_CLOEXEC,您可以按fcntl.fcntl(sys.stdout,fcntl.F_GETFD)

进行测试

您描述的行为可以通过

在ubuntu16中重现
import os
import sys
import fcntl
print(1)
ret = fcntl.fcntl(sys.stdout, fcntl.F_GETFD)
ret |= fcntl.FD_CLOEXEC
fcntl.fcntl(sys.stdout, fcntl.F_SETFD, ret)
os.execl(sys.executable, sys.executable, '-c', 'print(2)')
print(3)

所以当你在PyCharm中运行时,它必须重定向stdout并设置等效的windows标志。