我正在编写一个执行scala命令的小型python应用程序。用户可以通过STDIN插入命令,然后python应用将其转发到scala解释器。执行命令后,应用程序将显示操作结果。
这个想法是用来Popen创建一个管道,通过该管道我可以发送命令并读取结果。这个想法很简单,但是没有用。我不明白的是,为什么在sys.stdin打开管道后它们不再起作用。这使得无法在python中读取命令。
Popen
sys.stdin
这是我正在使用的代码:
import sys from subprocess import Popen, PIPE with Popen(["scala"], stdout=PIPE, stdin=PIPE, bufsize=0, universal_newlines=True) as scala: while True: print("Enter scala command >>> ", end="") sys.stdout.flush() command = input() scala.stdin.write(command) scala.stdin.flush() print(scala.stdout.readline())
您需要从scala启动时开始读取所有行,然后以新行输入命令,并在获得以下两行输出之后:
from subprocess import Popen, PIPE with Popen(["scala"], stdout=PIPE, stdin=PIPE, bufsize=0, universal_newlines=True) as scala: for line in scala.stdout: print(line) if not line.strip(): break while True: command = input("Enter scala command >>> \n") scala.stdin.write(command+"\n") scala.stdin.flush() for line in scala.stdout: if not line.strip(): break print(line)
运行示例:
Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_60). Type in expressions to have them evaluated. Type :help for more information. Enter scala command >>> 3+4 scala> 3+4 res0: Int = 7 Enter scala command >>> 4 * 4 scala> 4 * 4 res1: Int = 16 Enter scala command >>> 16 / 4 scala> 16 / 4 res2: Int = 4
为了使它能够通过使用不带缓冲区的bash运行,似乎可以解决输出问题:
from subprocess import Popen, PIPE with Popen(["unbuffer", "-p","scala"], stdout=PIPE, stdin=PIPE, bufsize=0, universal_newlines=True) as scala: for line in scala.stdout: print(line) if not line.strip(): break while True: command = input("Enter scala command >>> ") scala.stdin.write(command+"\n") scala.stdout.flush() for line in scala.stdout: if not line.strip(): break print(line)
如果您使用的是Mac Os x,则可能应该使用:
with Popen(["script", "-q", "/dev/null", "scala"], stdout=PIPE, stdin=PIPE, bufsize=0, universal_newlines=True) as scala:
从bash:
print(line) ## -- End pasted text -- Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_60). Type in expressions to have them evaluated. Type :help for more information. Enter scala command >>> 4 + 2 scala> 4 + 2 res0: Int = 6 Enter scala command >>> 4 * 12 scala> 4 * 12 res1: Int = 48 Enter scala command >>> 100 // 25 scala> 100 // 25 res2: Int = 100 Enter scala command >>>
有关外壳缓冲区问题的更多信息: