【问题标题】:Python subprocess make a new window and keep executing commands in itPython子进程创建一个新窗口并继续在其中执行命令
【发布时间】:2021-12-16 19:34:55
【问题描述】:

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

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)

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

【问题讨论】:

  • 这只是 CMD 和大多数其他 shell 的正常行为。如果您提供要运行的命令,他们将运行它并退出。如果您在终端窗口中键入该命令也会发生同样的情况,它会创建一个新的 cmd 进程,运行给定的命令并退出。所以这不是 python 问题,而是您使用 cmd 的问题。
  • 也许您应该使用pexpect 启动cmd 而不使用任何命令,然后发送tree 之类的命令。或者也许你应该使用 subprocess 仅启动 cmd 并使用 stdint 发送 tree 和其他命令。

标签: python windows subprocess


【解决方案1】:

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

使用communicate() 而不是.stdin.write、.stdout.read 或.stderr.read 以避免由于任何其他操作系统管道缓冲区填满并阻塞子进程而导致的死锁。

找到here

其次,您不能像预期的那样使用子进程向进程发送多个命令。欲了解更多信息,请参阅here。

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

【讨论】:

    【解决方案2】:

    start cmd 似乎打破了我们的预期,但如果你只需要一个新的 shell,而不是一个新的窗口,试试这个,正如 @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 和wexpect 文档了解更多想法。

    祝你编码好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-06
      • 1970-01-01
      • 1970-01-01
      • 2020-03-30
      • 2021-10-09
      • 2012-02-26
      • 2012-03-08
      相关资源
      最近更新 更多