Reputation: 15387
On Python 3.5.1, I have the following:
output = subprocess.check_output(cmd).decode(encoding="UTF-8")
This calls the properly invoked command cmd
. C++14 code in cmd
looks like:
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)
Running the above Python code causes the subprocess cmd
to fail at the indicated line. According to the Python docs, in this case, the stdout/stderr should be inherited from the parent process (i.e., the Python interpreter). So, it shouldn't. In fact, the above works just fine for e.g. printf
ed output.
Attempting to redirect explicitly also fails:
#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.
What's going wrong? How do I fix it?
Upvotes: 1
Views: 512
Reputation: 414795
A pipe is not a console. check_output()
uses stdout=PIPE
internally. It won't redirect the console output (produced by WriteConsoleW()
).
The first error (invalid handle) suggests that the standard output is not the console device.
Unless it is a desired behavior (to print outside of the standard output); use WriteFile()
if stdout is not a console device.
The second error (io.UnsupportedOperation: fileno
) suggests that sys.stdout
is not a real file and therefore you can't pass it as stdout
parameter to a subprocess (you could redirect subprocess' stdout using stdout=PIPE
and print the output using print()
or sys.stdout.write()
method directly).
Upvotes: 2