我已经查看了这两个文档。
这个问题是由J.F.的评论提示的:Retrieving the output of subprocess.call()
subprocess.call()
的当前Python文档说明了如何将PIPE
用于subprocess.call()
:
注意请勿对此功能使用
stdout=PIPE
或stderr=PIPE
。子进程将阻塞它是否为管道生成足够的输出以填充OS管道缓冲区,因为没有读取管道。
Python 2.7 subprocess.call()
:
注意请勿对此函数使用
stdout=PIPE
或stderr=PIPE
,因为这可能会因子进程输出量而死锁。需要管道时,请使用Popen和communic()方法。
Python 2.6不包含此类警告。
此外,subprocess.call()
and subprocess.check_call()
似乎无法访问其输出,除了使用带有communication()的stdout = PIPE:
https://docs.python.org/2.6/library/subprocess.html#convenience-functions
请注意,如果您要将数据发送到流程的
stdin
,则需要使用Popen
创建stdin=PIPE
对象。同样,要在结果元组中获取除None之外的任何内容,您还需要提供stdout=PIPE
和/或stderr=PIPE
。
https://docs.python.org/2.6/library/subprocess.html#subprocess.Popen.communicate
subprocess.call()
和subprocess.Popen()
之间的差异使PIPE
的{{1}}安全性降低了吗?
更具体:为什么subprocess.call()
“死锁基于子进程输出量。”,而不是subprocess.call()
?
答案 0 :(得分:18)
call()
is just Popen().wait()
(± error handling)
您不应将stdout=PIPE
与call()
一起使用,因为它不会从管道中读取,因此子进程在填充相应的OS管道缓冲区后会立即挂起。这是一张显示数据如何在command1 | command2
shell管道中流动的图片:
你的Python版本是什么并不重要 - 管道缓冲区(看图片)不在Python进程之内。 Python 3不使用C stdio,但它只影响内部缓冲。刷新内部缓冲区后,数据将进入管道。如果command2
(您的父Python程序)没有从管道中读取,则command1
(子进程,例如,由call()
启动)将在管道缓冲区已满时挂起(/proc/sys/fs/pipe-max-size
我的Linux机器上{3}} ~65K(最大值为stdout=PIPE
~1M))。
如果您稍后从管道中读取,则可以使用Popen.communicate()
,例如,使用public static <N,E> void doGenericStatic2(N number, E element) {
System.out.println(number);
System.out.println(element);
}
方法。你也可以pipe_size = fcntl(p.stdout, F_GETPIPE_SZ)
。
答案 1 :(得分:2)
call
和Popen
都提供了访问命令输出的方法:
Popen
,您可以使用communicate
或向stdout=...
参数提供文件描述符或文件对象。call
,您唯一的选择是将文件描述符或文件对象传递给stdout=...
参数(您不能将communicate
用于此参数)。现在,stdout=PIPE
与call
一起使用时不安全的原因是因为call
在子流程完成之前不会返回,这意味着所有输出都必须在那个时刻驻留在内存中,如果输出量太多,那么就会填满操作系统管道。缓冲液中。
您可以验证以上信息的参考文献如下: