[英]difference between communicate() and .stdin.write, .stdout.read or .stderr.read - python
I wan to create a pipe between 3 commands: 我想在3个命令之间创建一个管道:
cat = subprocess.Popen("cat /etc/passwd", stdout=subprocess.PIPE)
grep = subprocess.Popen("grep '<usernamr>'", stdin=cat.stdout, stdout=subprocess.PIPE)
cut = subprocess.Popen("cut -f 3 -d ':'", stdin=grep.stdout, stdout=subprocess.PIPE)
for line in cut.stdout:
# process each line here
But python documentation says: 但python文档说:
Use
communicate()
rather than.stdin.write
,.stdout.read
or.stderr.read
to avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process.使用
communicate()
而不是.stdin.write
,.stdout.read
或.stderr.read
来避免由于任何其他OS管道缓冲区填满和阻塞子进程而导致的死锁。
then how should I use cut.stdout
? 那么我应该如何使用
cut.stdout
? Can someone explain documentation? 有人可以解释文档吗?
communicate
is designed to prevent a deadlock that wouldn't occur in your application anyway: it is there primarily for the situation where both stdin
and stdout
on a Popen
object are pipes to the calling process , ie communicate
旨在防止应用程序中不会发生的死锁:主要是因为Popen
对象上的stdin
和stdout
都是调用进程的管道,即
subprocess.Popen(["sometool"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
In your case, you can safely read from cut.stdout
. 在您的情况下,您可以安全地从
cut.stdout
读取。 You may use communicate
if you find it convenient, but you don't need to. 如果您觉得方便,可以使用
communicate
,但您不需要。
(Note that subprocess.Popen("/etc/passwd")
doesn't make sense; you seem to have forgotten a cat
. Also, don't forget shell=True
.) (注意
subprocess.Popen("/etc/passwd")
没有意义;你好像忘记了cat
。另外,不要忘记shell=True
。)
The external process you've spawned may block forever if you are using process.stdin.write
without any awareness of possible buffering issues. 如果您在
process.stdin.write
可能的缓冲问题的情况下使用process.stdin.write
则您生成的外部进程可能会永久阻塞。 For example, if the process responds to your 1-line input by writing to its stdout a large (say, 10-100MB) amount of data and you continue to write to its stdin while not receiving this data, than the process will become blocked on write to stdout (stdout is an unnamed pipe and the OS maintains buffers of a particular size for them). 例如,如果进程通过向其stdout写入大量(例如,10-100MB)数据并且在未接收到此数据的情况下继续写入其stdin而响应您的1行输入,则该进程将被阻止写入stdout(stdout是一个未命名的管道,操作系统为它们维护特定大小的缓冲区)。
You can try the iterpipes library that deals with these issues by running input and ouput tasks as separate threads. 您可以通过将输入和输出任务作为单独的线程运行来尝试处理这些问题的iterpipes库。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.