Я запускаю Gitolite над репозиторием Git, и у меня есть пост-прием. Скрипт этого крючка написан на Python и не удался после
proc = subprocess.Popen('git log', shell = True, stdout=subprocess.PIPE)
out = proc.stdout.read()
Он не выполняется после этих строк. Если я запускаю этот скрипт вручную, он работает отлично.
Что я делаю неправильно?
Из документации по подпроцессу:
Предупреждение
Используйте связь(), а не.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.
Ваша труба, вероятно, не вернется. Если это так, вы можете:
Запустите git с --no-pager
чтобы предотвратить зависание PAGER или GIT_PAGER.
Ограничьте вывод журнала с -n
флага -n
чтобы поддерживать выходной -n
на приемлемом уровне. В библиотеке подпроцессов четко сказано:
[T] его дочерний процесс может блокироваться, если он генерирует достаточный вывод в канал для заполнения буфера операционной системы.