Jus12
Jus12

Reputation: 18024

Executing shell commands from Scala REPL

An interesting feature of Scala REPL is if you drop any jar in your %SCALA_HOME%\lib directory, it is available for import from the REPL. I have several jars there, and I often need to find out which ones are available to be included. So I always have to open another command window and find out which jars exist in that directory. It would be great if the REPL allowed me to execute system commands such as dir or ls or at least list all the jars in the above lib directory. What is the easiest way (if any) to invoke shell commands in REPL ?

Upvotes: 16

Views: 10729

Answers (5)

Daniel C. Sobral
Daniel C. Sobral

Reputation: 297175

Here is a little-known trick of 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

Where <TAB> is I pressing tab.

Upvotes: 3

counter.culture
counter.culture

Reputation: 1

UPDATE 2018/01/15

Example: you like to see the files in the current working directory:

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

But you can't do this:

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

First you have to assign the lines to another type that supports iteration:

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)

Then iterate, and voila!

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

Upvotes: 0

jwvh
jwvh

Reputation: 51271

UPDATE

The means for extracting :sh output has changed over the years.

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)

Upvotes: 6

Nicolas
Nicolas

Reputation: 24769

In REPL the :sh command allow you to introduce shell command:

Windows version:

scala> :sh cmd /C dir
  res0: scala.tools.nsc.interpreter.ProcessResult = `cmd /C dir` (28 lines, exit 0)
scala> res0 foreach println

(unfortunately, there is no way to avoid the call to cmd \C before the shell command)

Unix-like version:

scala> :sh ls
  res0: scala.tools.nsc.interpreter.ProcessResult = `cmd /C dir` (28 lines, exit 0)
scala> res0 foreach println

Update: Inspired by Daniel's answer, a little trick for windows user:

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

scala> "dir".!

Upvotes: 24

Daniel C. Sobral
Daniel C. Sobral

Reputation: 297175

Alternative: use Scala's sys.process library:

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

Upvotes: 18

Related Questions