简体   繁体   English

捕获subprocess.run()的output还能实时打印?

[英]Capture the output of subprocess.run() but also print it in real time?

I would like to run a command using subprocess.run() and then get its stdout/stderr as a string, but I want the subprocess to also print its output to the console normally while running.我想使用subprocess.run()运行命令,然后将其 stdout/stderr 作为字符串获取,但我希望子进程在运行时也能正常将其 output 打印到控制台。 If I do如果我做

result = subprocess.run(['ls', '-al'])

then I can see the output printed to my console but I can't access the output after the command runs.然后我可以看到 output 打印到我的控制台,但在命令运行后我无法访问 output。 If I do如果我做

result = subprocess.run(['ls', '-al'], capture_output=True, text=True)

I can access result.stdout and result.stderr but nothing is printed to the console while the command is running.我可以访问result.stdoutresult.stderr但在命令运行时没有任何内容打印到控制台。 Can I have both printing to the console and saving to result.stdout ?我可以同时打印到控制台并保存到result.stdout吗?

From the documentation of subprocess.run :subprocess.run的文档中:

Run the command described by args.运行 args 描述的命令。 Wait for command to complete, then return a CompletedProcess instance.等待命令完成,然后返回 CompletedProcess 实例。
[...] [...]
If capture_output is true, stdout and stderr will be captured.如果capture_output为真,stdout 和 stderr 将被捕获。 When used, the internal Popen object is automatically created with stdout=PIPE and stderr=PIPE .使用时,内部 Popen object 使用stdout=PIPEstderr=PIPE自动创建。

The docs for subprocess.PIPE say: subprocess.PIPE的文档说:

Special value that can be used as the stdin , stdout or stderr argument to Popen and indicates that a pipe to the standard stream should be opened.可用作 Popen 的stdinstdoutstderr参数的特殊值,指示应打开标准stream的 pipe。 Most useful with Popen.communicate().对 Popen.communicate() 最有用。

The doc for the Popen constructor parameter stdout : Popen 构造函数参数stdout的文档:

stdin, stdout and stderr specify the executed program's standard input, standard output and standard error file handles, respectively. stdin、stdout 和 stderr 分别指定执行程序的标准输入、标准 output 和标准错误文件句柄。 Valid values are PIPE, DEVNULL, an existing file descriptor (a positive integer), an existing file object , and None .有效值为 PIPE、DEVNULL、现有文件描述符(正整数)、现有文件 objectNone

So using capture_output=True is a no-go, because the output will be stored in a pipe for you to read after the call finishes.所以使用capture_output=True是不行的,因为 output 将存储在 pipe 中供您在通话结束阅读。

The simpler is for you to use subprocess.Popen as @MatBBastos suggested, with wich you can communicate (repeatedly sending content to stdin and receiving content from stdout / stderr ).更简单的是您可以按照@MatBBastos 的建议使用subprocess.Popen ,您可以使用它进行communicate (反复将内容发送到stdin并从stdout / stderr接收内容)。 The solution linked is a bit dated (cf its own comments; Python 2) but should work well.链接的解决方案有点过时(参见它自己的评论;Python 2)但应该可以正常工作。 A related solution is this one.一个相关的解决方案是这个。

To keep using subprocess.run , you will have to provide a file descriptor as stdout parameter, which I don't know how would have to redirect to a file object that does what you want: writing to the standard stream, but also keeping a copy in memory for later use.要继续使用subprocess.run ,您必须提供一个文件描述符作为stdout参数,我不知道如何将其重定向到执行您想要的文件 object :写入标准 stream,但还要保持复制到 memory 供以后使用。
There are docs in the io module, and a lot of questions on Stack Overflow about doing things like that, but it is notably more difficult than the other way. io模块中有文档,Stack Overflow 上有很多关于这样做的问题,但它明显比其他方式更难。

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

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