繁体   English   中英

如何正确循环 subprocess.stdout

[英]How do I properly loop through subprocess.stdout

我正在创建一个程序,我需要使用 powershell session 并且我发现如何使用以下代码获得持久的 session。 但是,当命令运行时,我想遍历 powershell 的 output 的新行。 下面的for循环是我发现这样做的唯一方法,但它需要一个EOF并且没有得到它,所以它只是徘徊并且程序永远不会退出。 如何在标准输出中获取新行的数量,以便正确循环它们?

from subprocess import Popen, PIPE

process = Popen(["powershell"], stdin=PIPE, stdout=PIPE)

def ps(command):
    command = bytes("{}\n".format(command), encoding='utf-8')
    process.stdin.write(command)
    process.stdin.flush()

    process.stdout.readline()
    return process.stdout.readline().decode("utf-8")

ps("echo hello world")

for line in process.stdout:
    print(line.strip().decode("utf-8"))

process.stdin.close()
process.wait()

您需要 Powershell 命令才能知道何时退出。 通常,解决方案不仅仅是flush ,而是close子进程的stdin 当它完成工作并在其输入中找到 EOF 时,它应该自行退出。 只是改变:

process.stdin.flush()

至:

process.stdin.close()

这意味着flush并确保子进程知道输入已完成。 如果这本身不起作用,您可以在您实际运行的命令之后显式添加quitexit (无论 Powershell 用于手动终止 session)命令。

如果您必须在单个子进程中运行多个命令,并且在发送下一个命令之前必须完全使用每个命令,则可以使用可怕的启发式解决方案,例如一次发送三个命令,其中第二个简单地回显一个标记字符串,而第三个显式刷新标准输出(以确保块缓冲并不意味着当哨兵卡在子进程的内部缓冲区中时您死锁等待哨兵),并且一旦看到哨兵,您的循环就可以终止。 如果没有哨兵,情况会更糟,因为您基本上无法判断命令何时完成,只需要使用select / selectors模块来轮询进程的stdout ,超时,只要有可用数据就读取行,并假设如果在没有预期超时 window 的情况下没有可用的新输入,则该过程完成。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM