在Scala REPL中执行shell命令

16
Scala REPL有一个有趣的特性,如果您在%SCALA_HOME%\lib目录中放置任何jar文件,则可以从REPL进行导入。我有几个jar文件在那里,我经常需要查找哪些可用于包含。因此,我总是必须打开另一个命令窗口并找出该目录中存在哪些jar文件。如果REPL允许我执行系统命令,例如dirls,或者至少列出上述lib目录中的所有jar文件,那将是很好的。在REPL中调用shell命令的最简单方法(如果有)是什么?
5个回答

24

在 REPL 中,:sh 命令允许您引入 shell 命令:

Windows 版本:

scala> :sh cmd /C dir
  res0: scala.tools.nsc.interpreter.ProcessResult = `cmd /C dir` (28 lines, exit 0)
scala> res0 foreach println
抱歉,无法避免在执行 shell 命令之前调用 cmd \C,这是不可避免的。
类Unix版本:
scala> :sh ls
  res0: scala.tools.nsc.interpreter.ProcessResult = `cmd /C dir` (28 lines, exit 0)
scala> res0 foreach println

更新:受到Daniel's answer的启发,这里有一个适用于Windows用户的小技巧:

scala> implicit def stringToDosProcess(s: String) =
  scala.sys.process.stringToProcess("cmd /C "+ s)
stringToDosProcess: (s: String)scala.sys.process.ProcessBuilder

scala> "dir".!

谢谢!这是我所寻找的最接近的内容。 - Jus12
在Windows上对我不起作用:欢迎使用Scala 2.11.8(Java HotSpot(TM) 64-Bit Server VM,Java 1.8.0_121)。键入表达式进行评估。或尝试::help。scala> :sh cmd /C dir res0: scala.tools.nsc.interpreter.ProcessResult = `cmd /C dir` (27 lines, exit 0) scala> res0 foreach println :13: error: value foreach is not a member of scala.tools.nsc.interpreter.ProcessResult res0 foreach println ^ - Hossein
1
尝试使用res0.lines并遍历println。 - Amey Joshi
toDos,哈哈! :) - user unknown

18

替代方案:使用Scala的sys.process库:

scala> import sys.process._
import sys.process._

scala> "ls /home/dcs/scala-2.9.1.final".!
bin
doc
lib
man
meta
misc
src
res1: Int = 0

在Windows中,"dir"等(以及大多数有用的命令)不是单独的文件,而是嵌入在shell解释器中,因此虽然很酷但并不是很好。 - Jus12
我已更新我的答案,以便为Windows用户构建与此一样美味的东西。 - Nicolas
2
@Jus12 使用 cmd。问题是关于从 REPL 执行 shell 命令,实际问题是列出文件。我为每个问题提供了一个解决方案。 :-) - Daniel C. Sobral
是的,我同意。问题出在Windows上。不过你们两个回答都非常有用。 - Jus12
1
看起来对于非内置命令,你必须使用 Seq("cmdname", "arg1", "arg2") 来传递参数。 - Erik Kaplun

6

更新

多年来提取:sh输出的方法已经发生了变化。

Welcome to Scala 2.11.8 (OpenJDK 64-Bit Server VM, Java 1.8.0_91).
Type in expressions for evaluation. Or try :help.

scala> :sh date
res0: scala.tools.nsc.interpreter.ProcessResult = `date` (1 lines, exit 0)

scala> res0 foreach println
<console>:13: error: value foreach is not a member of scala.tools.nsc.interpreter.ProcessResult
       res0 foreach println
            ^

scala> res0.show
<console>:13: error: value show is not a member of scala.tools.nsc.interpreter.ProcessResult
       res0.show
            ^

scala> res0.lines
res3: List[String] = List(Sat Sep 17 19:29:26 PDT 2016)

3

这是REPL中一个鲜为人知的小技巧:

Welcome to Scala version 2.10.0-20120323-101508-45eebcf98d (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_26).
Type in expressions to have them evaluated.
Type :help for more information.

scala> /home/dcs/scala-2.9.1.final/<TAB>
/home/dcs/scala-2.9.1.final/misc   /home/dcs/scala-2.9.1.final/bin    /home/dcs/scala-2.9.1.final/man    /home/dcs/scala-2.9.1.final/src    /home/dcs/scala-2.9.1.final/lib    
/home/dcs/scala-2.9.1.final/meta   /home/dcs/scala-2.9.1.final/doc    

scala> /home/dcs/scala-2.9.1.final/lib/<TAB>
/home/dcs/scala-2.9.1.final/lib/scala-dbc.jar        /home/dcs/scala-2.9.1.final/lib/scala-swing.jar      /home/dcs/scala-2.9.1.final/lib/jline.jar            
/home/dcs/scala-2.9.1.final/lib/scala-library.jar    /home/dcs/scala-2.9.1.final/lib/scala-compiler.jar   /home/dcs/scala-2.9.1.final/lib/scalap.jar           

scala> /home/dcs/scala-2.9.1.final/lib/scala-library.jar
res0: scala.tools.nsc.io.File = /home/dcs/scala-2.9.1.final/lib/scala-library.jar

其中 <TAB> 表示我按下了 Tab 键。


你可以在编程中使用 REPL 插入 <TAB>,例如 "/ho<TAB>/dcs/scala-2.9<TAB>",至少在 Linux 上是这样的情况。 - virtualeyes

0

更新于2018/01/15

示例:您想查看当前工作目录中的文件:

scala> :sh ls -l
res3: scala.tools.nsc.interpreter.ProcessResult = `ls -l` (13 lines, exit 0)

但你不能这样做:

scala> res3.foreach {println}
<console>:40: error: value foreach is not a member of scala.tools.nsc.interpreter.ProcessResult
       res3.foreach {println}
            ^

首先,您必须将这些行分配给支持迭代的另一种类型:

scala> res3.lines
res7: List[String] = List(total 960, -rw-r--r--@  1 dave  staff   11325 Jan  3 15:01 LICENSE, -rw-r--r--@  1 dave  staff    8859 Jan  3 15:01 README.rst, drwxr-xr-x@  3 dave  staff      96 Jan  3 15:03 assembly, drwxr-xr-x@ 20 dave  staff     640 Jan  3 15:01 bin, drwxr-xr-x@ 13 dave  staff     416 Jan  3 15:01 doc, drwxr-xr-x@  7 dave  staff     224 Jan  3 15:01 docker, drwxr-xr-x@  6 dave  staff     192 Jan  3 15:03 examples, -rw-r--r--@  1 dave  staff     826 Jan  3 15:01 gradle.properties, -rw-r--r--@  1 dave  staff     128 Jan  3 15:04 h2o_drivers.txt, drwxr-xr-x   3 dave  staff      96 Jan 16 00:54 h2ologs, drwxr-xr-x@  5 dave  staff     160 Jan  3 15:04 py, -rw-r--r--@  1 dave  staff  455890 Sep 19 04:18 rsparkling.tar.gz)

然后迭代,就这样!
scala> res7.foreach {println}
total 960
-rw-r--r--@  1 dave  staff   11325 Jan  3 15:01 LICENSE
-rw-r--r--@  1 dave  staff    8859 Jan  3 15:01 README.rst
drwxr-xr-x@  3 dave  staff      96 Jan  3 15:03 assembly
drwxr-xr-x@ 20 dave  staff     640 Jan  3 15:01 bin
drwxr-xr-x@ 13 dave  staff     416 Jan  3 15:01 doc
drwxr-xr-x@  7 dave  staff     224 Jan  3 15:01 docker
drwxr-xr-x@  6 dave  staff     192 Jan  3 15:03 examples
-rw-r--r--@  1 dave  staff     826 Jan  3 15:01 gradle.properties
-rw-r--r--@  1 dave  staff     128 Jan  3 15:04 h2o_drivers.txt
drwxr-xr-x   3 dave  staff      96 Jan 16 00:54 h2ologs
drwxr-xr-x@  5 dave  staff     160 Jan  3 15:04 py
-rw-r--r--@  1 dave  staff  455890 Sep 19 04:18 rsparkling.tar.gz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接