从Python运行Shell命令并实时打印输出



我想编写一个函数,该函数一次执行多个shell命令并打印外壳实时返回的内容。

我当前有以下代码,该代码不打印外壳(我使用的是Windows 10和Python 3.6.2(:

commands = ["foo", "foofoo"]
p = subprocess.Popen("cmd.exe", shell=True, stdin=subprocess.PIPE, 
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)
for command in commands:
    p.stdin.write((command + "n").encode("utf-8"))
p.stdin.close()
p.stdout.read()

我如何看到外壳实时返回的内容?

编辑:这个问题不是评论中两个第一个链接的重复,它们无助于实时打印

可以在不同线程中处理stdinstdout。这样一来,一个线程就可以处理stdout的输出,另一个线程在stdin上写下新命令。但是,由于stdinstdout是独立的流,因此我认为这可以保证流中的顺序。对于当前的示例,它似乎按预期工作。

import subprocess
import threading
def stdout_printer(p):
    for line in p.stdout:
        print(line.rstrip())
commands = ["foo", "foofoo"]
p = subprocess.Popen("cmd.exe", stdin=subprocess.PIPE, 
                     stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                     universal_newlines=True)
t = threading.Thread(target=stdout_printer, args=(p,))
t.start()
for command in commands:
    p.stdin.write((command + "n"))
    p.stdin.flush()
p.stdin.close()
t.join()

另外,请注意,我正在按行编写stdout,这通常是可以的,因为它倾向于被缓冲并一次生成(或更多(。我想可以处理未封闭的 stdout流(或例如 stderr(by-character,如果是最好的。

我相信您需要这样的东西

commands = ["foo", "foofoo"]
p = subprocess.Popen("cmd.exe", shell=True, stdin=subprocess.PIPE, 
                 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
for command in commands:
    p.stdin.write((command + "n").encode("utf-8"))
out, err = p.communicate()
print("{}".format(out))
print("{}".format(err))

假设您想控制Python代码中的输出,您可能需要执行此类操作

import subprocess
def run_process(exe):
    'Define a function for running commands and capturing stdout line by line'
    p = subprocess.Popen(exe.split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    return iter(p.stdout.readline, b'')

if __name__ == '__main__':
    commands = ["foo", "foofoo"]
    for command in commands:
        for line in run_process(command):
            print(line)

最新更新