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

时间:2012-03-27 09:23:12

标签: python stdout pipe stdin stderr

我想在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

但python文档说:

  

使用communicate()而不是.stdin.write.stdout.read或   .stderr.read以避免由于任何其他OS管道导致的死锁   缓冲填充和阻止子进程。

那么我应该如何使用cut.stdout?有人可以解释文档吗?

2 个答案:

答案 0 :(得分:5)

communicate旨在防止您的应用程序中无法发生的死锁:它主要适用于stdinstdout Popen的情况对象是管道到调用进程,即

subprocess.Popen(["sometool"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)

在您的情况下,您可以安全地阅读cut.stdout。如果您觉得方便,可以使用communicate,但不需要。{/ p>

(请注意,subprocess.Popen("/etc/passwd")没有意义;您似乎忘记了cat。另外,请不要忘记shell=True。)

答案 1 :(得分:3)

如果您使用process.stdin.write而没有意识到可能的缓冲问题,那么您产生的外部进程可能会永久阻止。例如,如果进程通过向其stdout写入大量(例如,10-100MB)数据并且在未接收到此数据的情况下继续写入其stdin而响应您的1行输入,则该进程将被阻止写入stdout(stdout是一个未命名的管道,操作系统维护特定大小的缓冲区)。

您可以通过将输入和输出任务作为单独的线程运行来尝试处理这些问题的iterpipes库。