auf Python 3.5.1, ich habe folgendes:Python Standard IO Subprocess
output = subprocess.check_output(cmd).decode(encoding="UTF-8")
Dies ruft die ordnungsgemäß Befehl aufgerufen cmd
. C++ 14-Code in cmd
wie folgt aussieht:
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
assert(handle!=INVALID_HANDLE_VALUE); //Always passes
assert(handle!=nullptr); //Always passes
CONSOLE_SCREEN_BUFFER_INFO csbi;
BOOL result = GetConsoleScreenBufferInfo(handle,&csbi);
assert(result!=0); //Always fails. `GetLastError()` returns 6 (invalid handle)
den oben Python-Code Ausführen das subprocess verursacht cmd
bei der angegebenen Linie zum Scheitern verurteilt. Gemäß den Python-Dokumenten sollte in diesem Fall das stdout/stderr vom übergeordneten Prozess (d. H. Dem Python-Interpreter) geerbt werden. Also sollte es nicht. In der Tat funktioniert das obige für z.B. printf
Ed-Ausgabe.
ausdrücklich auch umleiten Der Versuch schlägt fehl:
#Traceback (most recent call last):
# File "C:\dev\Python35\lib\subprocess.py", line 914, in __init__
# errread, errwrite) = self._get_handles(stdin, stdout, stderr)
# File "C:\dev\Python35\lib\subprocess.py", line 1145, in _get_handles
# c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
#io.UnsupportedOperation: fileno
p = subprocess.Popen(cmd.split(" "),stdout=sys.stdout,stderr=sys.stderr)
#Using `subprocess.PIPE` instead fails in the same way as the `subprocess.check_output(...)`
#example originally given above.
Was falsch los ist? Wie repariere ich es?
'check_output' setzt' stdout = PIPE'. Sie können dieses Handle nicht mit Konsolenfunktionen wie 'GetConsoleScreenBufferInfo' und' WriteConsole' verwenden. 'printf' funktioniert, weil es' WriteFile' aufruft, das Bytes in jede Art von Datei-Handle schreibt. – eryksun
Ist 'sys.stdout' ein Dateiobjekt in einer IDE? In diesem Fall handelt es sich nicht um eine Betriebssystemdatei mit einem Handle, die in den Standardhandles des untergeordneten Prozesses vererbt werden kann. Wenn Ihr C++ - Code darauf zurückgreift, C-Standard-I/O zu verwenden (vorzugsweise unbuffered), wenn es sich bei stdout nicht um eine Konsole handelt, kann Ihr Python-Code einen Thread verwenden, um aus der Pipe 'p.stdout' zu lesen. 'check_output' und' Popen.communicate' machen das für dich, aber du brauchst vielleicht etwas interaktiveres. – eryksun
@HarryJohnston, wir wissen, dass 'sys.stdout' nicht mit einer Windows-Datei (Konsole, Pipe, Festplatte) verbunden ist, weil es kein' fileno() 'hat. Ich denke, imallett möchte, dass die Standardausgabe des Child-Prozesses in Pythons 'sys.stdout' auftaucht, unabhängig davon, was' sys.stdout' ist (zB 'sys.stdout' könnte ein Proxy-Objekt sein, das mit dem interaktiven Fenster einer IDE kommuniziert ein Rohr oder eine Steckdose). In diesem Fall kann ein Thread "p.stdout.read (1)" oder "p.stdout.readline()" durchlaufen und in "sys.stdout" schreiben. – eryksun