Giu*_*Pes 6 python subprocess pipe
我正在编写一个执行scala命令的小型python应用程序.用户可以通过STDIN插入命令,然后python应用程序将它们转发给scala解释器.执行命令后,应用程序将显示操作结果.
我的想法是用来Popen创建一个管道,我可以通过它发送命令和读取结果.这个想法很简单,但它不起作用.我不明白的是,为什么sys.stdin管道打开后它不再起作用了.这使得无法在python中读取命令.
这是我正在使用的代码:
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())
Run Code Online (Sandbox Code Playgroud)
您需要读取 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)
Run Code Online (Sandbox Code Playgroud)
运行示例:
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
Run Code Online (Sandbox Code Playgroud)
要让它在 bash 中工作,使用unbuffer运行它似乎可以解决输出问题:
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)
Run Code Online (Sandbox Code Playgroud)
如果您使用的是 Mac Os x,您可能应该使用:
with Popen(["script", "-q", "/dev/null", "scala"], stdout=PIPE, stdin=PIPE, bufsize=0, universal_newlines=True) as scala:
Run Code Online (Sandbox Code Playgroud)
来自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 >>>
Run Code Online (Sandbox Code Playgroud)
有关 shell 缓冲区问题的更多信息: