Почему мой крюк после получения зависает при чтении из канала подпроцесса?

1

Я запускаю Gitolite над репозиторием Git, и у меня есть пост-прием. Скрипт этого крючка написан на Python и не удался после

proc = subprocess.Popen('git log', shell = True, stdout=subprocess.PIPE)
out = proc.stdout.read()

Он не выполняется после этих строк. Если я запускаю этот скрипт вручную, он работает отлично.

Что я делаю неправильно?

  • 3
    Добро пожаловать в StackOverflow. Пожалуйста, улучшите ваш вопрос, разместив соответствующие разделы вашего кода, правильно отформатированные. Кроме того, пожалуйста, опубликуйте фактическое сообщение об ошибке, которое вы получили, и какие шаги вы уже предприняли для исследования вашей проблемы программирования.
  • 0
    Ну, вот что я сделал. Как упомянуто здесь stackoverflow.com/questions/4844880/… Я попытался указать полный путь к команде и параметр «cwd» подпроцесса. Я не получаю никаких сообщений об ошибках, если я их получу, я смогу самостоятельно исследовать эту проблему.
Показать ещё 1 комментарий
Теги:
subprocess
pipe

2 ответа

1
Лучший ответ

Из документации по подпроцессу:

Предупреждение

Используйте связь(), а не.stdin.write,.stdout.read или.stderr.read, чтобы избежать взаимоблокировок из-за того, что любой из других буферов операционной системы заполняет и блокирует дочерний процесс.

Я бы не стал использовать shell=True если это возможно (IMO это полезно, только если вы хотите использовать встроенные оболочки и специфичные для платформы/оболочки) и передать команду Popen в виде списка, например ['git', 'log']

Попробуйте что-нибудь вроде:

>>> proc = subprocess.Popen(['git', 'log'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> proc.communicate()
('', 'fatal: Not a git repository (or any of the parent directories): .git\n')

communicate()[0] - это stdout, communicate()[1] - stderr.

  • 0
    Спасибо, этот метод отлично работает.
0

Ваша труба, вероятно, не вернется. Если это так, вы можете:

  1. Запустите git с --no-pager чтобы предотвратить зависание PAGER или GIT_PAGER.

  2. Ограничьте вывод журнала с -n флага -n чтобы поддерживать выходной -n на приемлемом уровне. В библиотеке подпроцессов четко сказано:

    [T] его дочерний процесс может блокироваться, если он генерирует достаточный вывод в канал для заполнения буфера операционной системы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню