私はGitリポジトリ上でGitoliteを実行しており、そこに受信後のフックがあります。Pythonで書かれたこのフックのスクリプトは、後に失敗します
proc = subprocess.Popen('git log', shell = True, stdout=subprocess.PIPE)
out = proc.stdout.read()
これらの行の後には実行されません。このスクリプトを手動で実行すると、完璧に機能します。
私が間違っているのは何ですか?
私はGitリポジトリ上でGitoliteを実行しており、そこに受信後のフックがあります。Pythonで書かれたこのフックのスクリプトは、後に失敗します
proc = subprocess.Popen('git log', shell = True, stdout=subprocess.PIPE)
out = proc.stdout.read()
これらの行の後には実行されません。このスクリプトを手動で実行すると、完璧に機能します。
私が間違っているのは何ですか?
警告
.stdin.write、.stdout.read、または.stderr.readではなくcommunicate()を使用して、他のOSパイプバッファーがいっぱいになり子プロセスをブロックすることによるデッドロックを回避します。
可能であれば使用も避け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
フラグで制限して、パイプ出力を適切なサイズに維持します。サブプロセスライブラリは明確に次のように述べています。
[T]子プロセスは、OSパイプバッファをいっぱいにするのに十分な出力をパイプに生成する場合、ブロックする可能性があります。