我正在努力解决子流程和管道背后的概念,并在Python上下文中使用它们。如果有人能够对这些问题有所了解,那将真正帮助我。
说我的管道设置如下
createText.py | processText.py | cat
processText.py正在通过stdin接收数据,但这是如何实现的?它是如何知道没有更多数据将会出现并且应该退出?我的猜测是它可以寻找一个EOF并根据它终止,但是如果createText.py永远不会发送一个呢?这会在createText.py的部分被视为错误吗?
假设parent.py启动子子进程(child.py)并调用wait()以等待子进程完成。如果父母将孩子的stdout和stderr作为管道捕获,在孩子终止后是否仍然可以安全地从他们那里读取?或者当一端终止时,管道(及其中的数据)被破坏了吗?
我想解决的一般问题是编写一个python脚本,该脚本使用Popen类多次调用rsync。我希望我的程序等到rsync完成,然后我想检查返回状态以查看它是否正确退出。如果没有,我想阅读孩子的stderr,看看错误是什么。这是我到目前为止所拥有的
# makes the rsync call. Will block until the child
# process is finished. Returns the exit code for rsync
def performRsync(src, dest):
print "Pushing " + src + " to " + dest
child = Popen(['rsync', '-av', src, dest], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
child.wait()
## check for success or failure
## 0 is a successful exit code here
if not child.returncode:
return True
else:#ballz
stout, sterr = child.communicate()
print "ERR pushing " + src + ". " + sterr
return False
更新:我也遇到过这个问题。考虑这两个简单的文件:
# createText.py
for x in range(1000):
print "creating line " + str(x)
time.sleep(1)
# processText.py
while True:
line = sys.stdin.readline()
if not line:
break;
print "I modified " + line
为什么processText.py在这种情况下不会开始打印,因为它从stdin获取数据?管道在传递之前是否收集了一些缓冲数据?
答案 0 :(得分:1)
这假设是UNIXish / POSIXish环境。
管道中的EOF不再需要读取数据,即read()
返回长度为0.这通常发生在左侧进程退出并关闭其stdout时。由于您无法从另一端关闭的管道中读取,因此processText中的read
表示EOF。
如果createText没有退出,从而关闭它的输出,那么它将是一个非结束程序,它在管道中是一件坏事。即使不在管道中,一个永远不会结束的程序通常也是错误的(奇怪的情况,如yes(1)
除外)。
只要您没有获得EOF或IOError(errno.EPIPE)指示,您也可以从管道读取,这也表明没有任何内容可供阅读。
我没有测试过您的代码,是否有意外的事情?