我想在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
?有人可以解释文档吗?
答案 0 :(得分:5)
communicate
旨在防止您的应用程序中无法发生的死锁:它主要适用于stdin
和stdout
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库。