本文介绍了从 Python 运行 shell 命令并实时打印输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to write a function that will execute multiple shell commands one at a time and print what the shell returns in real time.

我目前有以下不打印外壳的代码(我使用的是 Windows 10 和 python 3.6.2):

I currently have the following code which does not print the shell (I am using Windows 10 and 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返回的内容?

How can I see what the shell returns in real time ?

这个问题不是评论中前两个链接的重复,它们无助于实时打印.

Edit : This question is not a duplicate of the two first links in the comments, they do not help printing in real time.

推荐答案

可以在不同的线程中处理 stdinstdout.这样,一个线程可以处理打印 stdout 的输出,另一个线程可以在 stdin 上编写新命令.但是,由于 stdinstdout 是独立的流,我认为这不能保证流之间的顺序.不过,对于当前示例,它似乎按预期工作.

It is possible to handle stdin and stdout in different threads. That way one thread can be handling printing the output from stdout and another one writing new commands on stdin. However, since stdin and stdout are independent streams, I do not think this can guarantee the order between the streams. For the current example it seems to work as intended, though.

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),如果这样更可取.

Also, note that I am writing stdout line by line, which is normally OK, since it tends to be buffered and being generated a line (or more) at a time. I guess it is possible to handle an unbuffered stdout stream (or e.g. stderr) character-by-character instead, if that is preferable.

这篇关于从 Python 运行 shell 命令并实时打印输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 17:27