从线程中使用 Python Subprocess.Popen

37 投票
2 回答
86690 浏览
提问于 2025-04-15 12:12

我正在尝试在一个线程里使用子进程模块和Popen来启动一个'rsync'命令。在我调用rsync之后,我还需要读取它的输出。我使用了communicate方法来读取输出。当我不使用线程时,代码运行得很好。但是,当我使用线程时,communicate这个调用就卡住了。我还注意到,当我把shell设置为False时,在线程中运行时communicate没有任何返回。

2 个回答

18

这里有一个很棒的实现方法,它没有使用线程:在进程运行时不断打印子进程的输出

import subprocess

def execute(command):
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = ''

    # Poll process for new output until finished
    for line in iter(process.stdout.readline, ""):
        print line,
        output += line


    process.wait()
    exitCode = process.returncode

    if (exitCode == 0):
        return output
    else:
        raise Exception(command, exitCode, output)

execute(['ping', 'localhost'])
47

你没有提供任何代码让我们查看,不过这里有一个示例,做的事情和你描述的类似:

import threading
import subprocess

class MyClass(threading.Thread):
    def __init__(self):
        self.stdout = None
        self.stderr = None
        threading.Thread.__init__(self)

    def run(self):
        p = subprocess.Popen('rsync -av /etc/passwd /tmp'.split(),
                             shell=False,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)

        self.stdout, self.stderr = p.communicate()

myclass = MyClass()
myclass.start()
myclass.join()
print myclass.stdout

撰写回答