I have a subprocess that either quits with a returncode, or asks something and waits for user input.
I would like to detect when the process asks the question and quit immediately. The fact that the process asks the question or not is enough for me to decide the state of the system.
The problem is that I cannot read the question because the child process probably does not flush standard output. So I cannot rely on parsing subprocess.Popen().stdout
: when trying to read it, well, it blocks because input is being read first.
A bit like this
# ask.py, just asks something without printing anything if a condition is met
# here, we'll say that the condition is always met
input()
Of course, the actual subprocess is a third party binary, and I cannot modify it easily to add the necessary flush calls, which would solve it.
I could also try the Windows equivalent of unbuffer
(What is the equivalent of unbuffer program on Windows?) which is called winpty
, which would (maybe) allow me to detect output and solve my current issue, but I'd like to keep it simple and I'd like to solve the standard input issue first...
I tried... well, lots of things that don't work, including trying to pass a fake file as stdin
argument, which doesn't work because subprocess
takes the fileno
of the file, and we cannot feed it rubbish...
p = subprocess.Popen(["python","ask.py"],...)
Using communicate
with a string doesn't work either, because you cannot control when the string is read to be fed to the subprocess (probably through a system pipe).
Those questions were promising but either relied on standard output, or only apply to Linux
- Detecting when a child process is waiting for input
- How can I know whether my subprocess is waiting for my input ?(in python3)
What I'm currently doing is running the process with a timeout, and if the timeout is reached, I then decide that the program is blocked. But it costs the timeout waiting time. If I could decide as soon as stdin
is read by the subprocess, that would be better.
I'd like to know if there's a native python solution (possibly using ctypes
and windows extensions) to detect read from stdin. But a native solution that doesn't use Python but a non-Microsoft proprietary language could do.