Python 子进程创建一个新的 window 并继续在其中执行命令

Python subprocess make a new window and keep executing commands in it

我想使用 subprocess.Popen 或任何替代方法来生成一个新的终端 window 并继续向其提供命令,其输出显示在同一终端 window 中。 到目前为止我已经试过了

import subprocess
i=subprocess.Popen("start cmd /K tree",creationflags=subprocess.CREATE_NEW_CONSOLE,stdin=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
i.stdin.write(b"echo hi\n")

out=i.stdout.read()
print(out)

但是只有第一个命令树执行而回显不执行 在这里它运行 tree 并在关闭终端后停在那里 window 程序结束而不执行 echo 命令

所以首先,要与进程通信,您应该使用 subprocess.communicate() 而不是 stdin.write。来自子流程的文档:

Use communicate() rather than .stdin.write, .stdout.read or .stderr.read to avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process.

找到here

其次,您无法像预期的那样向带有子进程的进程发送多个命令。有关详细信息,请参阅

第三,如果你真的想发送更多命令,你必须使用其他库,对于linux你可以使用pexpect for windows you can use wexpect但是两者都没有最近的变化(要么它们不在活动状态下发展,或者他们已经很完美了 ;))

start cmd 似乎打破了预期,但如果您只需要一个新的 shell,而不是一个新的 window,请按照@furas 和@D-E-N 的建议试试这个:

import wexpect

print("Wexpect Example:")

# Create the child process
child = wexpect.spawn("cmd.exe")
child.expect_exact(">")

# If you only expect a prompt after each command is complete, this should be fine
list_of_commands = ["tree",
                    "echo hi\n", ]
for c in list_of_commands:
    child.sendline(c)
    child.expect_exact(">")
    print(child.before)

# Exit will close the child implicitly, but I add the explicit child.close() anyway
child.sendline("exit")
child.close()

print("Script complete. Have a nice day.")

输出

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Try the new cross-platform PowerShell https://aka.ms/pscore6

PS C:\Users\Rob\source\repos\Wexpect> python wexpect.py
Wexpect Example:
tree
Folder PATH listing for volume Windows-SSD
Volume serial number is XXXX-XXXX
C:.
├───folder1
├───folder2
│   ├───sub-folder2.1
│   └───sub-folder2.3
└───folder3

C:\Users\Rob\source\repos\Wexpect
echo hi
hi

C:\Users\Rob\source\repos\Wexpect
Script complete. Have a nice day.
PS C:\Users\Rob\source\repos\Wexpect> 

为简洁起见,我跳过了 EOF 和 TIMEOUT 错误的处理。查看 pexpect and wexpect 文档了解更多想法。

祝编码顺利!