【问题标题】:difference between communicate() and .stdin.write, .stdout.read or .stderr.read - pythoncommunicate() 和 .stdin.write、.stdout.read 或 .stderr.read 之间的区别 - python
【发布时间】:2012-04-10 19:32:23
【问题描述】:

我想在 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 避免由于任何其他操作系统管道导致的死锁 缓冲区填满并阻塞子进程。

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

【问题讨论】:

    标签: python stdout pipe stdin stderr


    【解决方案1】:

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

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 2016-01-23
        • 2014-02-04
        • 2013-05-14
        • 2020-05-06
        • 2016-11-07
        • 2021-06-10
        • 1970-01-01
        • 2016-04-02
        • 2021-01-02
        相关资源
        最近更新 更多