2009-06-12 3 views
21

Я пытаюсь запустить 'rsync', используя модуль подпроцесса и Popen внутри потока. После вызова rsync мне нужно также прочитать результат. Я использую метод связи для чтения вывода. Код работает нормально, когда я не использую нить. Похоже, что когда я использую поток, он зависает на вызове связи. Еще одна вещь, которую я заметил, это то, что когда я устанавливаю shell = False, я ничего не получаю от общения при запуске в потоке.Python Subprocess.Popen из потока

ответ

33

Вы не предоставили никакого кода для нас, чтобы посмотреть, но вот пример, который делает что-то подобное тому, что вы описали:

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 
+0

Да, это точно то, что я делаю. Тем не менее, я хотел бы прочитать результат внутри потока. Следует также отметить, что я использую Python 2.3. Я взял копию подпроцесса с 2.4. – noahd

+0

, тогда, пожалуйста, отметьте это как «ответил» –

+0

Мне должно быть более ясно, что это то, что я делаю, но это не работает. В этом случае вызов связи не возвращает ничего, и команда не появляется. Если я установлю shell = True, то связывается поток. Затем, после того как я остановил python, я заканчиваю несуществующий процесс ssh. – noahd

9

Вот большая реализация не используя темы: constantly-print-subprocess-output-while-process-is-running

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']) 
+4

Следует отметить, что эта реализация будет блокироваться на 'process.stdout.readline()'. – Ian

Смежные вопросы