Issue
I have a simple .exe file compiled from Haskell that just prints to stdout everything it receives to stdin:
module Main where
main = do
command <- getLine
putStrLn command
main
And I have a Python file that tries to send two lines to the subprocess:
from subprocess import Popen, PIPE, STDOUT
p = Popen(['main.exe'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
def send_command(arg):
print("Sending command: "+arg)
response = p.communicate(input=arg)[0].decode()
print("Response: "+response+"\n")
return response
send_command("Test1")
send_command("Test2")
It works the first time around, but not the second, apparently because it considers the input completed:
Sending command: Test1
Response: Test1
main.exe: <stdin>: hGetLine: end of file
Sending command: Test2
Traceback (most recent call last):
File ".\test.py", line 12, in <module>
send_command("Test2")
File ".\test.py", line 7, in send_command
response = p.communicate(input=arg)[0].decode()
File "C:\Python27\lib\subprocess.py", line 483, in communicate
return self._communicate(input)
File "C:\Python27\lib\subprocess.py", line 722, in _communicate
self.stdin.write(input)
ValueError: I/O operation on closed file
I don't know if the fault lies with Python or Haskell; other subprocesses for as expected when called from Python, and the Haskell file works as expected when called from the command line, but they just refuse to work together. How to fix this?
Edit:
I replaced the communicate
with direct read\write:
from subprocess import Popen, PIPE, STDOUT
p = Popen(['main.exe'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
def send_command(arg):
print("Sending command: "+arg)
p.stdin.write(arg+"\n")
response = p.stdout.readline().decode()
print("Response: "+response+"\n")
return response
send_command("Test1")
send_command("Test2")
And made sure (just in case) that the .exe properly terminates lines:
module Main where
main = do
command <- getLine
putStrLn (command ++ "\n")
main
And now the program just stops and does nothing at this point:
Sending command: Test1
Am I supposed to somehow "flush" the input or what?
Solution
Here is the documentation for the subprocess.Popen.communicate
function you're calling:
Popen.communicate(input=None, timeout=None)
Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate.
(my emphasis).
You can just write to p.stdin
and read from p.stdout
if you don't want all the other stuff communicate
does.
I don't know if the fault lies with Python or Haskell
This isn't intended as a criticism, but a helpful hint: the fault lies with whoever didn't read the documentation for the function they called. It's free, read it!
Answered By - Useless Answer Checked By - David Marino (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.