【发布时间】:2020-05-17 01:48:30
【问题描述】:
我已经关注了一些关于捕获子流程输出的 SO 问题。在子进程中使用 git 似乎输出到错误而不是 stdout 或 stderr
这就是我想从 shell 复制的内容。
git add .
git commit -m 'commit message blah'
git push -u origin master
跟踪每个阶段的输出。 在此示例中,我没有要提交的更新。
$git add .
$ git commit -m 'wip'
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
按照下面的代码,我正在使用
output = run("git add .", check=True, capture_output=True, shell=True)
并检查 output.returncode,但遇到 CalledProcessError 而不是要输出的值。 有任何想法吗?我可以通过错误捕获来伪造功能,但这远非最佳。
我无法从 'git push' 捕获“没有提交,工作树干净”的输出,这看起来很奇怪。 '' stderr & stdout 的值也是如此。 'git commit' 之后的 returncode 是 0。
nb: 'git 添加。'不会在 shell 中产生任何输出。
环境:Windows 10 上的 ubuntu 应用程序。Python3,anaconda 64 位。
from subprocess import *
import sys
try:
print("start git add.")
#output = run("git add .", check=True, stdout=PIPE, stderr=PIPE, shell=True)
output = run("git add .", check=True, capture_output=True, shell=True)
print("git add completed.")
print("output.stderr:", "'"+output.stderr.decode('utf-8')+"'")
print("output.stdout:", "'"+output.stdout.decode('utf-8')+"'")
print("output.stderr==None:", output.stderr==None)
print("output.stdout==None:", output.stdout==None)
print("output.returncode:", output.returncode)
if output.returncode==0:
output=None
print("start git commit.")
#output = run(f"git commit -m 'commit message three'", check=True, stdout=PIPE, stderr=PIPE, shell=True)
output = run("git commit -m 'commit message three'", check=True, capture_output=True, shell=True)
#exits to exception here when error occurs dueing git commit.
print("git commit completed.")
print("output.stderr:", output.stderr.decode('utf-8'))
print("output.stdout:", output.stdout.decode('utf-8'))
print("output.stderr==None:", output.stderr==None)
print("output.stdout==None:", output.stdout==None)
print("output.returncode:", output.returncode)
if output.returncode==0:
output=None
print("start git push.")
#output = run("git push -u origin master -f", check=True, stdout=PIPE, stderr=PIPE, shell=True)
output = run("git push -u origin master -f", capture_output=True)
print("git push completed.")
print("output.stderr:", output.stderr)
print("output.stdout:", output.stdout)
print("output.stderr==None:", output.stderr==None)
print("output.stdout==None:", output.stdout==None)
print("output.returncode:", output.returncode)
if output.returncode==0:
print("success @ git push, output.returncode==0.")
except CalledProcessError as error:
print("CalledProcessError error caught.")
print('CalledProcessError:An exception occurred: {}'.format(error))
print("CalledProcessError:sys.exc_info()[0]:", sys.exc_info()[0])
print("CalledProcessError:output:", output)
print("CalledProcessError:output.stderr:", output.stderr)
print("CalledProcessError:output.stdout:", output.stdout)
此代码块的输出
start git add.
git add completed.
output.stderr: ''
output.stdout: ''
output.stderr==None: False
output.stdout==None: False
output.returncode: 0
start git commit.
CalledProcessError error caught.
CalledProcessError:An exception occurred: Command 'git commit -m 'commit message three'' returned non-zero exit status 1.
CalledProcessError:sys.exc_info()[0]: <class 'subprocess.CalledProcessError'>
CalledProcessError:output: None
Traceback (most recent call last):
File "<stdin>", line 15, in <module>
File "/home/bmt/anaconda3/lib/python3.7/subprocess.py", line 487, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command 'git commit -m 'commit message three'' returned non-zero exit status 1.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 41, in <module>
AttributeError: 'NoneType' object has no attribute 'stderr'
编辑:我的主要错误是使用 'check=True' 和 'shell=True' 还将 shell 命令从一个字符串更改为字符串列表。
output = run("git add .", check=True, capture_output=True, shell=True)
到
output = run(["git", "add", "."], capture_output=True)
【问题讨论】:
-
这不是 Python。写入标准错误的是 Git。您可能期望在标准输出上做的许多事情实际上都在标准错误中。并非所有事情都进入 stderr,只有许多你意想不到的事情。
-
然而,作为一般规则,您不应从任何程序调用任何 interactive Git 命令。 Git 由许多工具构建而成,其中许多工具非常适合从其他程序运行。使用这些工具,以非交互方式运行它们,以获得可预测的、可编程的结果。其中大部分可以在 Git 本身中得到更好的处理,但是
git add和git commit都可以以非交互方式使用,而且你已经在做这部分了。
标签: python-3.x git