如何在使用os.execl替换进程时重定向stdin / stdout / stderr
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在使用os.execl替换进程时重定向stdin / stdout / stderr相关的知识,希望对你有一定的参考价值。
请考虑以下示例脚本:
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。
答案
这不是关于PyCharm的错误,因为我无法用IDEA重现它。 IDEA正在使用与PyCharm相同的核心。
这是因为您启动脚本的方式。如果您使用Run
启动脚本,它可以正常工作。如果你用Debug
启动它,它不会。
因为Run
只是在终端中运行脚本,但Debug
将启动调试器并将该进程连接到此调试器。您看到的输出实际上来自调试器,但不是直接来自您的脚本。替换进程时,调试器不会重建与新创建进程的连接。
这就是为什么你没有得到2
输出。
另一答案
在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中运行时,它必须重定向标准输出并设置等效的Windows标志。
以上是关于如何在使用os.execl替换进程时重定向stdin / stdout / stderr的主要内容,如果未能解决你的问题,请参考以下文章
如何在通知点击时重定向到特定的 ViewController?