我想编写一个函数,该函数一次执行多个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()
我如何看到外壳实时返回的内容?
编辑:这个问题不是评论中两个第一个链接的重复,它们无助于实时打印。。
可以在不同线程中处理stdin
和stdout
。这样一来,一个线程就可以处理stdout
的输出,另一个线程在stdin
上写下新命令。但是,由于stdin
和stdout
是独立的流,因此我认为这可以保证流中的顺序。对于当前的示例,它似乎按预期工作。
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)