2015-10-12 5 views
6

Я пишу небольшое приложение python, которое выполняет команды scala. Пользователь может вставить команду через STDIN, а затем приложение python пересылает их в интерпретатор scala. После выполнения команды приложение показывает результат операции.команда ввода не работает при использовании с popen python

Идея состоит в использовании 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()) 
+0

ли работу скрипта, если вы жестко закодировать 'command' вместо чтения его с' input'? – Barmar

+0

@ Бармар Да, он делает. Я жестко программирую «4 + 5» как команду, и интерпретатор возвращает правильный результат. –

+1

'scala' может буферизировать свой вывод. – Barmar

ответ

4

Вы должны прочитать все строки из когда Скала начинает затем ввести команду с новой строки и получить две строки вывода после того, как:

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 

чтобы заставить его работать с Баш, запуская его с 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) 

Если вы используете Mac OS X, вы, вероятно, следует использовать:

with Popen(["script", "-q", "/dev/null", "scala"], stdout=PIPE, stdin=PIPE, bufsize=0, universal_newlines=True) as scala: 

От Баш:

 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 >>> 

Более подробную информацию о оболочки буферные вопросы:

+0

Я не знаю, почему у меня такая же проблема, даже с вашим кодом. Какую операционную систему ты используешь? Я использую Mac OSX. Я сейчас пытаюсь использовать Linux. –

+0

В Linux, похоже, работает –

+0

@GiuseppePes, да я использую ubuntu.Итак, последнее, что вы видите, это '' Enter scala command >>> "'? –

Смежные вопросы