退出状态为128的子流程调用

时间:2019-10-27 01:25:44

标签: python git subprocess

本质上,我试图使用子过程调用在特定的sha哈希处检出git commit。

但是,我不断收到错误subprocess.CalledProcessError: Command '['git', 'checkout', '62bbce43e']' returned non-zero exit status 128.

这是我的下面的代码:

with open(filename) as inputfile:
    reader = csv.reader(inputfile, delimiter=",")
    linecount = 0
    for row in reader:
        if linecount == 0:
            linecount += 1
        else:
            repo = str(row[0])
            sha = str(row[2])
            specificfile = str(row[3])
            linenum = int(row[4])
            cl("cd", repo)
            subprocess.check_output(['git', 'checkout', sha])
            print("checkout done")
            git("checkout", "-")

2 个答案:

答案 0 :(得分:1)

一个subprocess.check_output()调用实际上返回了输出(您也可以通过传递一个stderr参数来获取错误输出)。您可能想看看它是否使您在解释发生了什么情况时出错。

由于您遇到异常(意味着调用未完成,因此可能不会返回输出),因此您应该能够从以下异常成员之一获取输出:

try:
    output = subprocess.check_output(['git', 'checkout', sha], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
    print("Exception on process, rc=", e.returncode, "output=", e.output)

要做的一件事是,如果您实际上不是Git存储库中的,一些git命令往往会返回128。因此,我将通过以下方式查看您的cl("cd", repo)行之后的路径:

os.system("pwd")  # use "cd" for Windows.

如果您的cd子流程中运行,不会不会影响当前流程,因此您不一定要处于Git仓库。这肯定可以解释128返回码。

通过示例,下面的脚本显示了当我尝试在存储库外运行git命令时发生的情况:

>>> try:
...     output = subprocess.check_output(['git', 'checkout', '12345'])
... except subprocess.CalledProcessError as e:
...     print(e.returncode, e.output)
...

128 b'fatal: not a git repository (or any of the parent directories): .git\n'

如果事实证明您 在错误的目录中(即cl("cd", repo)语句正在运行子进程来更改目录),则应使用受Python编码的方法来更改目录(a)

import os
os.chdir(path)

这实际上更改了立即进程(Python解释器)的目录,而不是临时子进程。


(a)实际上,这通常是个好建议-尽可能使用特定于Python的东西(因为它大多是跨平台的),而不是生成子shell(本质上是平台) -特定)。

答案 1 :(得分:0)

除此之外,导致一个子shell命令chdir到达其他目录不会影响后续的单独子shell或子进程命令,而调用os.chdir会直接影响您的流程,因此会影响其子流程-请注意,这里还有两个附加选项:

  • subprocess函数均接受关键字cwd参数,其默认值为cwd=None。在此处提供字符串会导致Python仅针对该子进程调用os.chdir进入指定目录。

    查看详细信息here

  • Git本身提供了一个标志-C,它告诉Git尽早进行自己的chdir。要像使用git checkout一样调用cd path/to/repo; git checkout,请使用git -C path/to/repo checkout

    此标志是Git 1.8.5版中的新功能,因此,如果您的Git早于该版本,则您将没有git -C(但是,如果您的Git早于2.x,则升级时间已经很长了。 :-))。