Подпроцесс вызова со статусом выхода 128 - PullRequest
0 голосов
/ 27 октября 2019

По сути, я пытаюсь использовать вызов подпроцесса для извлечения git commit с определенным sha-хешем.

Однако я получаю сообщение об ошибке 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 ]

1 голос
/ 27 октября 2019
Вызов

A 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 команды имеют тенденцию возвращать 128, если выВы на самом деле не в репозиторий Git. Поэтому я буду искать путь, следующий за вашей 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-blessed для изменения каталогов (a) :

import os
os.chdir(path)

Это фактически изменяет каталог для немедленного процесса (интерпретатор Python), а не для временного подпроцесса.


(a) На самом деле это хороший совет в целом - используйте как можно больше специфических для Python вещей (так как они в основном кросс-платформенные), а не порождают суб-оболочку (которая по своей природе является платформой)-специфический).

0 голосов
/ 27 октября 2019

Помимо другого момента - то, что передача одной из команд под-оболочки chdir в другой каталог, не влияет на последующие отдельные команды под-оболочки или подпроцесса, тогда как вызов os.chdir напрямую влияет на вашу * 1004. * process и, следовательно, влияет на его подпроцессы. Обратите внимание, что здесь у вас есть две дополнительные опции:

  • Все функции subprocess принимают аргумент ключевого слова cwd, значение по умолчанию - cwd=None. При вводе строки здесь Python os.chdir попадает в указанный каталог только для этого одного вызова подпроцесса.

    Подробнее см. здесь .

  • Сам 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, обновление уже давно прошло :-)).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...