与popen python一起使用时,输入命令似乎不起作用

发布于 2021-01-29 14:56:45

我正在编写一个执行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())
关注者
0
被浏览
103
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    您需要从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 >>>
    

    有关外壳缓冲区问题的更多信息:



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看