简体   繁体   English

communic()和.stdin.write,.stdout.read或.stderr.read - python之间的区别

[英]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对象上的stdinstdout都是调用进程的管道,即

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM