Reputation: 147
Fairly new to python and currently using Python 3.5.2. I have a subprocess where I need to monitor the output, process it and display it via kivy. This works fine.
But there comes a point where the subprocess needs a reply to continue or exit. This is where I am utterly stuck.
chimp_cmd = 'sudo /usr/bin/mono ' + os.getcwd() + '/aDotNet.exe ' + aVeryLongListofParam # aVeryLongListofParam is read from a file
child = subprocess.Popen([chimp_cmd],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
stdin=subprocess.PIPE,
bufsize=0) # no difference with bufsize set to 1
# while loop that reads in the data
# do funky stuff with the output data, (this works and relies on a lot of starts with comparisons)
if ( (b''.join(MyOutputLineList).decode("utf-8) ).startswith("Would you like"):
# wait for the thread that gets the response - this works
if usrReply = UsrKeyReply.no:
print("received user no") # we get to here
# attempts at sending a reply:
ret_value = child.stdin.write(b'n\n') # this doesn't work for me
print(ret_value)
print("test1")
os.system('pidof mono') # for debug
elif usrReply = UsrKeyReply.yes:
print("received user yes") # also get to this point
stdout, stderr = child.communicate(input=b'n\n')[0]
# child.stdin.flush() <-- this hangs the code
print("test2") # doesn't work for me either
Other details. On Ubuntu. The python scirpt is invoked with:
sudo python3 myscript.py
Yes it needs to be sudo because mono needs access to a USB port.
DotNet.exe is third party
DotNet.exe works fine if invoked directly from the command line.
I know that the message does not get back to the subprocess because apart from nothing happens, I can open another terminal and monitor the child with:
sudo strace -p <mono's PID>
Here I can see the exe going through the motions and playing nicely with the python script, and I see the prompt "Would you like..."
When the python script reaches the point of sending back the reply the child doesn't terminate (when 'n') or continue (when 'y')
Help!
As suggested by @Hermann I have tried changing to:
bufsize=1,
universal_newlines=True)
also amended the reply to
stdout, stderr = child.communicate(input='n\n')[0]
child.stdin.flush()
The script hangs after this.
Any more ideas?
Upvotes: 1
Views: 528
Reputation: 147
After further investigation, it turns out that python does indeed send data to the subprocess. The problem lies with how the input is handled on the C# side.
Console.ReadKey().Key /* this will not work with python subprocess piped stdin */
versus
piped_reply = Console.ReadLine() /* will work with python piped stdin */
See SO question: C# Console receive input with pipe
Upvotes: 1
Reputation: 637
You can flush the write buffer explicitly by calling child.stdin.flush()
.
Alternatively, you can try adding bufsize=1
and universal_newlines=True
in your subprocess.Popen
call for switching line-buffered mode. Note that the behaviour varies wildly accross Python 3 versions as mentioned in the various comments in subprocess stdin buffer not flushing on newline with bufsize=1.
Upvotes: 1