如何为外部命令提供输入?

时间:2014-04-05 19:39:16

标签: scala

根据我的理解,Scala可以运行系统命令并接收其输出。我正在为我的系统命令编写一个Web客户端,所以说我需要执行命令,接收输出,根据输出我可以给它一个命令。我想继续这样做,直到用户杀死命令。我已经阅读了一些关于ProcessIO的内容,我已经得到了从scala运行并接收输出的命令,但我怎样才能给它输入?

编辑:我正在寻找的是,我用scala调用命令。我调用的命令要求输入,用户将输入提供给scala程序,然后将其传递给被调用的程序。

示例:

Scala计划 - >呼叫系统程序 - >系统程序要求输入用户名和密码 - > Scala Program程序然后要求用户和用户提供输入的用户名和密码 - > Scala程序将输入传递给系统程序。

我想在提供输入的同时保持这个过程活着。

2 个答案:

答案 0 :(得分:4)

请考虑以下带重定向的示例

import scala.sys.process._
import java.io.File

"""echo -e hello\nworld""" #> new File("hello") !

new File ("hello") #> """grep world -c""" !!

提供1

这会将回显的字符串写入输出文件;接下来,现在输入文件被重定向到系统命令。

<强>更新

命令

"""echo -e hello\nworld""" #> """grep world -c""" !!

使用重定向并将结果作为字符串传递。这可以避免中间文件。

答案 1 :(得分:1)

我无法从您的问题中判断出您是否打算让用户向控制台提供除stdin以外的输入。虽然我怀疑你希望Scala程序中“完全包含”这一点,但我还是无法解决这个问题。但是,如果使用控制台是可以接受的,这里是一个简单的Scala程序的示例,它要求输入用户名/密码,另一个Scala程序启动它并使用Process.run(true)将调用的程序的out / err连接到控制台输入可以提供给控制台。

SimpleProgram测试输入:

package so

import java.util.Scanner

object SimpleProgram extends App {

  def getInput(prompt: String): Option[String] = {
    print( s"$prompt: " )
    val sc = new Scanner(System.in)
    sc.hasNextLine match {
      case true => val out = sc.nextLine
        if( out.length > 1 ) Some(out) else None
      case _ => None
    }
  }

  while( true ) {
    (getInput("username"), getInput("password")) match {
      case (Some(u), Some(p)) => println( s"Logged in as $u" ); System.exit(0)
      case _ => println( "Invalid input.  Please try again." )
    }
  }
}

这是调用ProcessBuilder的程序(类路径不能用于更改):

package so

import scala.sys.process._

object ProcessBuilderTest extends App {

  val classpath = "<path to>/scala-library.jar:./classes"
  val pb = Process("java", Seq("-cp", classpath, "so.SimpleProgram" ))
  pb.run(true) // all the magic happens here.
}

在这种情况下,Process基本上只是将调用的程序包装在ProcessBuilder中。我无法使用提供的方法使用ProcessIO同时吃掉适当的字符,仍然会杀死流等。我的猜测是,查看工作run(true)的情况会很有启发性

以下是使用更正的类路径运行后者的控制台记录示例:

username: foo
password: 
Invalid input.  Please try again.
username: foo
password: bar
Logged in as foo

我正在使用“java”来运行Scala代码,因为除了通过Eclipse之外我没有在我的mac上安装Scala。从Eclipse开始,ProcessBuilderTest从两个类的项目目录运行,输出目录设置为“classes”而不是“bin”。