python close用法_管道传输时在python的子流程模块中使用stdout.close()

In the python subprocess module, if we wanted to run the shell command

foo | grep bar

from within python, we might use

p1 = Popen(["foo"], stdout = PIPE)

p2 = Popen(["grep", "bar"], stdin = p1.stdout, stdout = PIPE)

p1.stdout.close()

output = p2.communicate()[0]

I'm confused about the line p1.stdout.close(). If you'll forgive me, I'll trace through how I think the program works, and the error will hopefully reveal itself.

It seems to me that when the line output = p2.communicate()[0] is enacted by python, python tries to call p2, it recognizes that it needs output from p1. So it calls p1, which executes foo and throws the output on the stack so that p2 can finish executing. And then p2 finishes.

But nowhere in this trace does p1.stdout.close() actually happen. So what is actually happening? It seems to me that this ordering of lines might matter too, so that the following wouldn't work:

p1 = Popen(["foo"], stdout = PIPE)

p1.stdout.close()

p2 = Popen(["grep", "bar"], stdin = p1.stdout, stdout = PIPE)

output = p2.communicate()[0]

And that's the status of my understanding.

解决方案

p1.stdout.close() is necessary for foo to detect when the pipe is broken e.g., when p2 exits prematurely.

If there is no p1.stdout.close() then p1.stdout remains open in the parent process and even if p2 exits; p1 won't know that nobody reads p1.stdout i.e., p1 will continue to write to p1.stdout until the corresponding OS pipe buffer is full and then it just blocks forever.

To emulate foo | grep bar shell command without a shell:

#!/usr/bin/env python3

from subprocess import Popen, PIPE

with Popen(['grep', 'bar'], stdin=PIPE) as grep, \

Popen(['foo'], stdout=grep.stdin):

grep.communicate()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值