【问题标题】:How do I work with a Scala process interactively?如何以交互方式使用 Scala 进程?
【发布时间】:2018-02-17 08:35:15
【问题描述】:

我正在使用 Scala 为使用文本输入和输出的游戏编写机器人。所以我想以交互方式处理进程——也就是说,我的代码从进程接收输出,使用它,然后才将下一个输入发送到进程。所以我想给一个函数同时访问 inputStreams 和 outputStream。

这似乎不适合 scala.sys.process.BasicIO 中的任何工厂或 scala.sys.process.ProcessIO 的构造函数(三个函数,每个函数只能访问一个流)。

这是我目前的做法。

private var rogue_input: OutputStream = _
private var rogue_output: InputStream = _
private var rogue_error: InputStream = _

Process("python3 /home/robin/IdeaProjects/Rogomatic/python/rogue.py --rogomatic").run(
  new ProcessIO(rogue_input = _, rogue_output = _, rogue_error = _)
)

try {
  private val rogue_scanner = new Scanner(rogue_output)
  private val rogue_writer = new PrintWriter(rogue_input, true)

  // Play the game
} finally {
  rogue_input.close()
  rogue_output.close()
  rogue_error.close()
}

这可行,但感觉不像 Scala。有没有更惯用的方法来做到这一点?

【问题讨论】:

    标签: scala process io


    【解决方案1】:

    所以我想以交互方式处理进程 - 也就是说,我的代码从进程接收输出,使用它,然后才将其下一个输入发送到进程。

    一般来说,这通常由expect 解决。存在受 expect 启发的各种语言的库和工具,包括 Scala:https://github.com/Lasering/scala-expect

    项目的自述文件提供了各种示例。虽然我不知道您的rouge.pystdin/stdout 交互的期望究竟是什么,但这里有一个快速的“hello world”示例,展示了如何与 Python 解释器交互(使用 Ammonite REPL,它具有方便的库导入功能):

    import $ivy.`work.martins.simon::scala-expect:6.0.0`
    
    import work.martins.simon.expect.core._
    import work.martins.simon.expect.core.actions._
    
    import scala.concurrent.ExecutionContext.Implicits.global
    import scala.concurrent.duration._
    
    val timeout = 5 seconds
    
    val e = new Expect("python3 -i -", defaultValue = "?")(
        new ExpectBlock(
          new StringWhen(">>> ")(
            Sendln("""print("hello, world")""")
          )
        ),
        new ExpectBlock(
          new RegexWhen("""(.*)\n>>> """.r)(
            ReturningWithRegex(_.group(1).toString)
          )
        )
      )
    
    e.run(timeout).onComplete(println)
    

    上面的代码所做的是它“期望”>>> 被发送到stdout,当它发现时,它会发送print("hello, world"),后跟一个换行符。从那时起,它使用正则表达式读取并返回所有内容,直到下一个提示 (>>>)。

    在其他调试信息中,以上内容应导致Success(hello, world) 被打印到您的控制台。

    该库有各种其他样式,并且可能还存在其他类似的库。我的主要观点是expect-inspired library 很可能是您正在寻找的。​​p>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多