繁体   English   中英

为什么从子进程管道读取时我的接收后钩子挂起了?

[英]Why does my post-receive hook hang while reading from a subprocess pipe?

我在Git存储库上运行Gitolite,并且在那里有接收后钩子。 这个钩子的脚本是用Python编写的,之后失败

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

这些行之后不执行。 如果我手动运行此脚本,则效果很好。

我做错了什么?

子流程文档中

警告

使用communication()而不是.stdin.write,.stdout.read或.stderr.read来避免死锁,这是由于其他任何OS管道缓冲区中的任何一个填满并阻塞了子进程造成的。

我也尽量避免使用shell=True (IMO,它仅在您想使用shell内置插件且特定于平台/ shell的情况下才有用),并将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]是标准输出, communicate()[1]是标准错误。

您的管道可能不返回。 如果是这样,您可以:

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

  2. 使用-n标志限制日志输出,以将管道输出保持在合理的大小。 子流程库明确指出:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM