2016-07-29 8 views
2

У меня возникли проблемы с пониманием того, почему это висит. Я разделил этот пример на основные компоненты. У меня есть файл, давайте назовем его do_ls.pyЗапуск команды Fabric в отдельной группе процессов Подвеска

import fabric.api 
import time 

host = "myhost.mydomain" 
username = "username" 
password = "password" 

def main(): 
    with fabric.api.settings(host_string=host,user=username,password=password): 
     result = fabric.api.run("ls") 

if __name__ == "__main__": 
    main() 

Если я запускаю эту команду: python do_ls.py он будет выполняться правильно. Теперь о проблеме. Я хотел бы запустить это в своем собственном процессе. Поэтому у меня есть этот файл, давайте назовем его main.py

import sys 
import os 
import logging 
import subprocess as sp 
import time 

def main(): 
    logging.basicConfig(level=logging.DEBUG) 
    cmd = [sys.executable, "/path/to/do_ls.py"] 
    p = sp.Popen(cmd, preexec_fn=os.setpgrp) 
    while p.poll() is None: 
     print "Sleeping..." 
     time.sleep(0.5) 
    print "All Done." 

if __name__ == "__main__": 
    main() 

Теперь, если я бегу python main.py это будет висеть вечно. Проблема, насколько мне известно, заключается в том, что я запускаю процесс в подгруппе (т. Е. Если я вывожу preexec_fn=os.setpgrp, тогда он будет работать правильно). Я не понимаю, почему это так. Особенно с учетом того, что следующие работы:

cmd = ["ssh", "-q", "[email protected]", "ls"] 
    p = sp.Popen(cmd, preexec_fn=os.setpgrp) 

Любое понимание было бы весьма полезным.

ответ

1

Поскольку следующие строки работы:

cmd = ["ssh", "-q", "[email protected]", "ls"] 
p = sp.Popen(cmd, preexec_fn=os.setpgrp) 

но main.py непрерывно висит, я полагаю, что

while p.poll() is None: 

никогда не вычисляет False. Поэтому p.poll() должен всегда возвращаться None, возможно, даже после завершения процесса. Быстрый поиск возвращал this conversation на сайт отчетов об ошибках Python. Согласно этому разговору, попробуйте позвонить sp.Popen() с (незарегистрированной) вариант _deadstate='dead':

Проблема заключается в том, что os.wait() не дружат с subprocess.py. Popen.poll() и Popen.wait() use os.waitpid(pid, ...), который будет повысить OSError, если pid уже зарегистрирован os.wait(). Popen.poll() swallows OSError и по умолчанию возвращает None.

Вы можете (сорт) исправить свою программу, используя p.popen(_deadstate='dead') вместо p.popen(). Это сделает poll() return 'dead' вместо None, если OSError попадает, но этот недокументирован.

+0

Адрес: Hey Ryan. Спасибо за ответ. Я все еще использую опрос в «рабочем» примере, я просто заменил ту команду, которую я выполнял. Извините, если эта часть запуталась. Поэтому я не думаю, что это проблема. Я просто говорил, что работает другая команда. Еще раз спасибо. – loganasherjones