2016-07-29 37 views
2

Ich habe Probleme zu verstehen, warum genau das hängt. Ich habe dieses Beispiel auf die Kernkomponenten reduziert. Ich habe eine Datei, nennen wir es do_ls.pyAusführen von Fabric-Befehl in separater Prozessgruppe Hängen

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() 

Wenn ich diesen Befehl ausführen: python do_ls.py es korrekt ausgeführt wird. Jetzt für das Problem. Ich möchte das in seinem eigenen Prozess ausführen. Also habe ich diese Datei haben, machen wir es 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() 
nennen

nun für immer, wenn ich python main.py diese hängen wird laufen. Das Problem, soweit ich weiß, ist, dass ich den Prozess in einer Untergruppe (d. H., Wenn ich preexec_fn=os.setpgrp herausnehmen, dann wird es richtig funktionieren). Was ich nicht verstehe ist, warum das so ist. Vor allem vorausgesetzt, dass die folgenden funktioniert:

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

Jeder Einblick würde sehr geschätzt werden.

Antwort

1

Da die folgenden Zeilen arbeiten:

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

aber main.py kontinuierlich hängt, Ich gehe davon aus, dass

while p.poll() is None: 

nie False auswertet. So muss p.poll() immer None zurückgegeben werden, möglicherweise sogar nach Abschluss des Prozesses. Eine schnelle Suche ergab this conversation auf Pythons Fehlermeldungsseite. Gemäß diesem Gespräch versucht sp.Popen() mit der (undokumentierte) _deadstate='dead' Option Aufruf:

Das Problem ist, dass os.wait() nicht gut mit subprocess.py spielt. Popen.poll() und Popen.wait() verwenden Sie os.waitpid(pid, ...), die OSError auslösen wird, wenn PID bereits von os.wait() gemeldet wurde. Popen.poll() schluckt OSError und gibt standardmäßig None zurück.

Sie können Ihr Programm (Art) reparieren, indem Sie p.popen(_deadstate='dead') anstelle von p.popen() verwenden. Dies macht poll()'dead' anstelle von None zurück, wenn OSError gefangen wird, aber das ist undokumentiert.

+0

Hey Ryan. Danke für die Antwort. Ich benutze immer noch die Abfrage im "Arbeits" -Beispiel, ich ersetzte einfach den Befehl, den ich ausführte. Entschuldigung, wenn dieser Teil verwirrend war. Also ich denke nicht, dass das das Problem ist. Ich sagte nur, dass ein anderer Befehl funktionierte. Danke noch einmal. – loganasherjones