根据我的理解,Scala可以运行系统命令并接收其输出。我正在为我的系统命令编写一个Web客户端,所以说我需要执行命令,接收输出,根据输出我可以给它一个命令。我想继续这样做,直到用户杀死命令。我已经阅读了一些关于ProcessIO的内容,我已经得到了从scala运行并接收输出的命令,但我怎样才能给它输入?
编辑:我正在寻找的是,我用scala调用命令。我调用的命令要求输入,用户将输入提供给scala程序,然后将其传递给被调用的程序。
示例:
Scala计划 - >呼叫系统程序 - >系统程序要求输入用户名和密码 - > Scala Program程序然后要求用户和用户提供输入的用户名和密码 - > Scala程序将输入传递给系统程序。
我想在提供输入的同时保持这个过程活着。
答案 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”。