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

时间:2018-02-13 17:42:27

标签: python shell subprocess

我想编写一个函数,一次执行一个shell命令,然后打印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()

如何实时查看shell返回的内容?

编辑:此问题与评论中的两个第一个链接不重复,它们无法帮助实时打印

3 个答案:

答案 0 :(得分:0)

我相信你需要这样的东西

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))

答案 1 :(得分:0)

假设您想要在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)

答案 2 :(得分:0)

可以在不同的线程中处理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),如果这是可取的。