How to execute system commands in scala - scala

i am new at scala and i am trying to run this simple program that get input from the user and execute it in the operation system:
import scala.io._
import sys.process._
object MyCmd {
def main(args: Array[String]) = {
print("> ")
var inputString = StdIn.readLine()
while(!inputString.trim().equals("exit")) {
var proc = stringToProcess(inputString)
println( proc.!!)
print("> ")
inputString = StdIn.readLine()
}
}
}
but when i'm running it:
c:\IDE\scala\test>scala MyCmd
> dir
java.io.IOException: Cannot run program "dir": CreateProcess error=2, The
system cannot find the file specified
...
Any help will be much appreciate

sys.process.ProcessBuilder not runnig Windows cmd command.
See Executing shell commands from Scala REPL
If you need to use the cmd command, you can execute as
val proc = stringToProcess("cmd /C "+inputString)
println(proc.!!)

Related

How to get return code in sbt of another internal command (not external command)?

My build.sbt file is like the following:
import sys.process._
def makeProject = Command.args("make", "<args>") {
(state, args) => {
val exec = Exec("run", None);
val makeCommand = ("make " + args.mkString(" "));
val newState = MainLoop.processCommand(exec, state);
// run is an internal command of sbt which can be executed from sbt terminal
// what I need is the return code of the `run` INTERNAL command
// if(exec's execution failed) do not execute the following makeCommand
makeCommand!;
newState;
}
}
I need to get the return code of Exec("run", None). If it ran successfully, the makeCommand after it should be executed - otherwise, do not execute the makeCommand.
You can define a task which depends on an internal task, like this:
myTask := {
val x = run.value
val args = Seq("my", "args")
val makeCommand = ("make " + args.mkString(" "))
makeCommand!
}
Now how to make the args more easily settable? I would suggest the most sbt idiomatic way would be to define them as settings in the build.sbt, and depend on them in your task.

Run Scala application on different process

Hi I want to create a program that starts another application on a new process:
object A{
def main(args: Array[String]) {
Process(????).run
println("new process has been created")
}
}
the application that should run on the new process:
object B{
def main(args: Array[String]) {
print("Hello world")
}
}
I know I can run a script using Process(script_string_to_run), but I don't know how to make it run another application..
Run Scala program from another Scala program
Scala Program
B.scala
object B {
def main(args: Array[String]): Unit = println("hello world")
}
Now execute the above program like this from another Scala program.
scala> import sys.process._
import sys.process._
scala> "scala B.scala" !!
warning: there was one feature warning; re-run with -feature for details
res1: String =
"hello world
"
Note that the file name of the file is same as the object name containing main method. This way scala would recognise the main class/object and execute the main method of the program. If the name of the file is not the name of the object containing the main method then It would not know what to execute.
! gives the exit status of the program after execution whereas !! gives the output of the program.
scala> import sys.process._
import sys.process._
scala> val status = "scala B.scala" !
warning: there was one feature warning; re-run with -feature for details
hello world
status: Int = 0
scala> val output = "scala B.scala" !!
warning: there was one feature warning; re-run with -feature for details
output: String =
"hello world
Scala Script
Test.sh
#!/usr/bin/env scala
object B{
def main(args: Array[String]) {
print("Hello world")
}
}
B.main(Array[String]())
Now Just run the B program using
"./Test.sh" !!
Command Line Activity
➜ cd demo
➜ demo ./Test.sh
zsh: permission denied: ./Test.sh
➜ demo chmod +rwx Test.sh
➜ demo ./Test.sh
Hello world%
➜ demo ./Test.sh
Hello world%
➜ demo scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_45).
Type in expressions for evaluation. Or try :help.
scala> import sys.process._
import sys.process._
scala> "./Test.sh" !!
warning: there was one feature warning; re-run with -feature for details
res0: String =
"Hello world
"
scala> :q

Execute shell script from scala application

I want to execute the sh file from Scala application.
Let's say I have createPassword.sh file and I need to invoke this sh file from Scala application and get the output back.
How can I achieve through scala application?
This should do the trick if the script is in the current working directory (otherwise specify the full path of the script)
import sys.process._
val result = "./createPassword.sh" !!
result is then a String containing the standard output (and standard error)
EDIT: If you want to use ProcessBuillder from Java SE7, you can also use this in scala:
import java.io.{BufferedReader, InputStreamReader}
val p = new ProcessBuilder("/bin/bash","createPassword.sh")
val p2 = p.start()
val br = new BufferedReader(new InputStreamReader(p2.getInputStream()))
var line:String = ""
while ({line = br.readLine(); line!= null}) {
println(line)
}
Given your dir has a script,
`val path = "./src/test/tests/Integration/"`
`val output = Process("sh test.sh", new File("path")).!!`

How to run external process in Scala and get both exit code and output?

How to call an external process and read both of its exit code and standard out, once it finished?
Using sys.Process will result in an exception being thrown on different exit code than 0 for success.
Try this:
import sys.process._
val stdout = new StringBuilder
val stderr = new StringBuilder
val logger = ProcessLogger(stdout append _, stderr append _)
val status = "ls -al " ! logger
println(status)
println("stdout: " + stdout)
println("stderr: " + stderr)
Then you got both of them: status, stdout and stderr.
Have you looked at Process.exitValue?
Returns the exit value for the subprocess.
(I've asked this question on freenode #java and was requested to post here if I found a solution, so here goes)
Simple approach is to use sys.ProcessBuilder:
def RunExternal(executableName: String, executableDir: String) : (Int, List[String]) = {
val startExecutionTime = System.currentTimeMillis()
val pb : ProcessBuilder = new ProcessBuilder (executableName)
pb.directory(new java.io.File(executableDir))
val proc = pb.start()
proc.waitFor()
val exitCode = proc.exitValue()
val output = scala.io.Source.fromInputStream(proc.getInputStream).getLines.toList
val executionTime = System.currentTimeMillis() - startExecutionTime
logger.info(String.format(s"Process exited with exit code: ${exitCode}."))
logger.info(String.format(s"Process took ${executionTime} milliseconds."))
(exitCode, output)
}

Using scala.sys.process with timeout

I find it extreemly cool to use standard syntax like
import scala.sys.process._
val countLogger = ProcessLogger(line => {println ("out line: " + line)},
line => {println ("err line: " + line)})
val exitCode = ("cat prog.c" #&& "gcc prog.c -o prog -lm"
#&& "echo running, this may hang" #&& "prog.exe") ! countLogger
println("exitCode = " + exitCode)
It however happens that last process hangs. Is it possible to kill it on timeout?
You can wrap your process in a Future(blocking(_)) and if it doesn't return after the time-out, you call process.destroy().
That's what I have done for my small Processor library, e.g. see here. Instead of using ! to eagerly wait for the exit-code, you use the run method. Here is an adaption from the README:
import scala.concurrent._
import ExecutionContext.Implicits.global
import scala.sys.process._
val p = "sleep 100".run() // start asynchronously
val f = Future(blocking(p.exitValue())) // wrap in Future
val res = try {
Await.result(f, duration.Duration(2, "sec"))
} catch {
case _: TimeoutException =>
println("TIMEOUT!")
p.destroy()
p.exitValue()
}