Python | subprocess执行git语句的换行问题

使用subprocess执行git clone时,希望python的输出模拟终端执行命令的模式。

第一版

刚开始使用的方法是用subprocess.PIPE捕获stdout,并把stderr重定向到stdout。

1
2
3
4
5
6
7
8
9
10
11
12
def exec_command_local(command):
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout = []
while True:
output_line = process.stdout.readline()
if output_line == "" and process.poll() is not None:
break
if output_line:
stdout.append(output_line)
print(f"{output_line}",end="")

return stdout

第二版

第一版代码运行时,发现捕获到的文本特别少。

然后在这里找到了原因:

1
When not writing to a terminal, git clone doesn't have any output to either stdout or stderr, except on error.

When not writing to a terminal, git clone doesn’t have any output to either stdout or stderr, except on error.
当没有写入终端时,git clone不会向stdoutstderr输出任何内容,除非发生错误。

同时答主也给了两个解决方案:

1、使用伪终端,但答主和题主在评论区的交流中提到伪终端无法在windows上使用,我就是windows上要用,我也没去验证新版的python支持不支持。
2、使用git的--progress参数,这样git无论有没有在终端中运行,都会打印出完整信息。

我使用了方案2,在拼接git命令时加上了--progress参数,就不贴代码了。

第三版

第二版代码确实能捕获到很多信息,但是全都是以\n结尾的,导致我一个git命令可能要输出几百行,信息太多了。

后来想了想,确实没有什么异步的必要,也不对返回值做解析,就改成这样:

1
subprocess.run(command, shell=True, check=True)

换成run得了😅