如何使从 Python 调用的 Haskell suprocess 在使用一次后不关闭?
How to make a Haskell suprocess called from Python to not close after one use?
我有一个从 Haskell 编译而来的简单 .exe 文件,它只将接收到的所有内容打印到标准输出:
module Main where
main = do
command <- getLine
putStrLn command
main
我有一个 Python 文件试图向子进程发送两行:
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")
第一次有效,但第二次无效,显然是因为它认为输入已完成:
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
不知道是Python还是Haskell的问题;当从 Python 调用时,其他子进程按预期工作,并且 Haskell 文件从命令行调用时按预期工作,但它们只是拒绝一起工作。如何解决这个问题?
编辑:
我用直接 read\write 替换了 communicate
:
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")
并确保(以防万一).exe 正确终止行:
module Main where
main = do
command <- getLine
putStrLn (command ++ "\n")
main
现在程序在此时停止并且什么都不做:
Sending command: Test1
我应该以某种方式 "flush" 输入还是什么?
这是您正在调用的 subprocess.Popen.communicate
函数的文档:
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.
(我的重点)。
如果您不想要 communicate
需要的所有其他内容,您可以只写入 p.stdin
并从 p.stdout
读取。
I don't know if the fault lies with Python or Haskell
这不是批评,而是有用的提示:错误在于没有阅读他们所调用函数的文档的人。免费,快来读吧!
我有一个从 Haskell 编译而来的简单 .exe 文件,它只将接收到的所有内容打印到标准输出:
module Main where
main = do
command <- getLine
putStrLn command
main
我有一个 Python 文件试图向子进程发送两行:
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")
第一次有效,但第二次无效,显然是因为它认为输入已完成:
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
不知道是Python还是Haskell的问题;当从 Python 调用时,其他子进程按预期工作,并且 Haskell 文件从命令行调用时按预期工作,但它们只是拒绝一起工作。如何解决这个问题?
编辑:
我用直接 read\write 替换了 communicate
:
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")
并确保(以防万一).exe 正确终止行:
module Main where
main = do
command <- getLine
putStrLn (command ++ "\n")
main
现在程序在此时停止并且什么都不做:
Sending command: Test1
我应该以某种方式 "flush" 输入还是什么?
这是您正在调用的 subprocess.Popen.communicate
函数的文档:
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.
(我的重点)。
如果您不想要 communicate
需要的所有其他内容,您可以只写入 p.stdin
并从 p.stdout
读取。
I don't know if the fault lies with Python or Haskell
这不是批评,而是有用的提示:错误在于没有阅读他们所调用函数的文档的人。免费,快来读吧!