我想使用subprocess.run()
运行一个命令,然后将其stdout/stderr作为字符串,但我希望子进程在运行时也能正常地将其输出打印到控制台。如果我做
result = subprocess.run(['ls', '-al'])
然后我可以看到打印到控制台的输出,但在命令运行后我无法访问输出。如果我做
result = subprocess.run(['ls', '-al'], capture_output=True, text=True)
我可以访问result.stdout
和result.stderr
,但在命令运行时,控制台上不会打印任何内容。我可以打印到控制台并保存到result.stdout
吗?
来自subprocess.run
:的文档
运行args描述的命令。等待命令完成,然后返回CompletedProcess实例
[…]
如果capture_output为true,则将捕获stdout和stderr。使用时,会使用stdout=PIPE
和stderr=PIPE
自动创建内部Popen对象。
subprocess.PIPE
的文档说:
特殊值,可用作Popen的stdin、tdout或stderr参数,指示应打开通往标准流的管道。Popen.communicate((.最有用
Popen构造函数参数stdout
:的文档
stdin、stdout和stderr分别指定执行程序的标准输入、标准输出和标准错误文件句柄。有效值为PIPE、DEVNULL、现有文件描述符(正整数(、现有文件对象和
None
。
因此,使用capture_output=True
是不可行的,因为输出将存储在管道中,以便在调用完成后读取。
更简单的方法是按照@MatBBastos的建议使用subprocess.Popen
,使用它可以communicate
(重复向stdin发送内容,并从stdout/tderr接收内容(。链接的解决方案有点过时(参见它自己的评论;Python 2(,但应该可以很好地工作。一个相关的解决方案就是这个。
要继续使用subprocess.run
,您必须提供一个文件描述符作为stdout
参数,我不知道如何重定向到一个执行您想要的操作的文件对象:写入标准流,但也在内存中保留一个副本以备日后使用
io模块中有文档,Stack Overflow上有很多关于做类似事情的问题,但它明显比其他方式更困难。