为什么我的post-receive挂钩在从子进程管道读取时挂起?

时间:2012-06-06 14:48:31

标签: python git subprocess pipe

我在Git存储库上运行Gitolite,我在那里有post-receive hook。用Python编写的这个钩子的脚本在

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

在这些行之后不会执行。如果我手动运行此脚本,它将完美无缺。

我做错了什么?

2 个答案:

答案 0 :(得分:1)

来自subprocess documentation

  

警告

     

使用communic()而不是.stdin.write,.stdout.read或   .stderr.read以避免由于任何其他OS管道导致的死锁   缓冲填充和阻止子进程。

如果可能的话,我会避免使用shell=True(IMO只有在你想使用shell内置函数并且它是特定于平台/ shell时才有用),并将Popen命令作为列表传递,例如{{1} }

尝试类似:

['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') 是stdout,communicate()[0]是stderr。

答案 1 :(得分:0)

您的烟斗可能没有返回。如果是这种情况,您可以:

  1. 使用--no-pager标志运行git,以防止PAGER或GIT_PAGER挂起进程。

  2. 使用-n标志限制日志输出,以将管道输出保持在合理的大小。 subprocess library清楚地说:

      

    [T]如果子进程为管道生成足够的输出以填充OS管道缓冲区,则子进程可能会阻塞。