Cuk*_*c0d 3 python windows subprocess
我遇到了一个问题:使用 Python 2.7,无法使用以下命令创建子进程
subprocess.Popen([.......], close_fds=True, stdout=subprocess.PIPE, ...)
Run Code Online (Sandbox Code Playgroud)
在 Windows 上,由于限制。在我的情况下需要使用close_fds,因为我不希望子进程继承已打开的文件文件描述符。这是在库中调用的,这意味着我无法控制已经打开的文件描述符(N标志)。
这是一个已知的错误,已在Python 3.4+上修复
我的问题是:如何使用子进程而不得到
如果重定向 stdin/stdout/stderr,则 Windows 平台不支持 close_fds
回答如下
此问题在 Python 3.7+ 上默认已修复
\n\n这绝对是一个棘手的黑客:答案是在使用模块之前迭代已经打开的文件描述符subprocess。
def _hack_windows_subprocess():\n """HACK: python 2.7 file descriptors.\n This magic hack fixes https://bugs.python.org/issue19575\n by adding HANDLE_FLAG_INHERIT to all already opened file descriptors.\n """\n # See https://github.com/secdev/scapy/issues/1136\n import stat\n from ctypes import windll, wintypes\n from msvcrt import get_osfhandle\n\n HANDLE_FLAG_INHERIT = 0x00000001\n\n for fd in range(100):\n try:\n s = os.fstat(fd)\n except:\n continue\n if stat.S_ISREG(s.st_mode):\n handle = wintypes.HANDLE(get_osfhandle(fd))\n mask = wintypes.DWORD(HANDLE_FLAG_INHERIT)\n flags = wintypes.DWORD(0)\n windll.kernel32.SetHandleInformation(handle, mask, flags)\nRun Code Online (Sandbox Code Playgroud)\n\n这是一个没有它就会崩溃的示例:
\n\nimport os, subprocess\nf = open("a.txt", "w")\nsubprocess.Popen(["cmd"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)\nf.close()\nos.remove(f.name)\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n回溯(最近一次调用最后一次):
\n\n文件“stdin”,第 1 行,模块中
\n\nWindowsError: [Error 32] Le processus ne peut pas acc\xc3\x9ader au\n fichier car ce fichier est utilis\xc3\x9a par un autre processus: \'a.txt\'
\n
现在修复:
\n\nimport os, subprocess\nf = open("a.txt", "w")\n_hack_windows_subprocess()\nsubprocess.Popen(["cmd"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)\nf.close()\nos.remove(f.name)\nRun Code Online (Sandbox Code Playgroud)\n\n作品。
\n\n希望我有帮助
\n| 归档时间: |
|
| 查看次数: |
3206 次 |
| 最近记录: |