Hey everyone, recently in my project, a need arises where I have to run an external command. In my code on a specific request, I wanted to start a node process. This made me ponder about “How to Execute Commands in Scala?”. 🤔
And I found something useful in Scala Library, so here I’m sharing what I learnt.
Process in Scala
There is a process package in Scala, which is based on Process and ProcessBuilder in Java. ProcessBuilder is a trait that implements process execution.
Just import :
Once this is imported, now you have different options for creating the ProcessBuilder and executing it. I’ll show you some examples to demonstrate them.
Creating a ProcessBuilder
By Implicit Conversations in Package Object
- Using String: This is the simplest way of creating a process, just write the command and add them in quotes.
//stringToProcess "node main.js".! //this will execute the node process
- Using a Sequence of String: In this, the first string is considered as a command and the following as arguments.
//stringSeqToProcess Seq("node", "main.js") ! //above will execute the node process
- Using a File: You can read/write from one file to another and that will be converted to a process.
//fileToProcess new File("test2.txt") #<< new File("test.txt") ! //above will append the data from test file to the test2 file
- Using a URL: You can read from a URL and write the content, or maybe do some other work with that. It will also be converted to a process.
//urlToProcess new URL("a valid url") #> new File("fixed.html") ! //copy the contents from the URL to the File
By Using Factory Methods Provided in Process’s Companion Object
//use Process.apply() method Process("node main.js") //This will simply execute the node process Process("node", Seq("main.js", "data.json")) //This way the first string is command, and in the Seq[String we can give n no. of arguments. Also here the arguments can be space as well.
There are many more that you can consider. You can even pass the working directory and environment variables if needed.
How to execute the command?
- run() : Run will execute the external command concurrently. It returns the Process immediately.
- ! : Starts the process and block until it exits. It returns the exit value.
- !! : Starts the process and block until it exits. It returns the output as String.
- lazyLines : Starts the process and return the output as LazyList. This will block when lines are not available and the process is not completed.
How to combine two ProcessBuilder?
- #| : It will pipe the output of one process to another. In this case, both the process are executed in parallel.
- ### : This can be used when two ProcessBuilder needs to be executed synchronously.
- #&& : By using this we can run this command first and then the other if this one succeeds.
- #|| : This will run this command first and then the other command if the first does not succeed.
By using above you can construct a complex or a sequence of command and execute it.
Also we have 3 methods to control a process when it is returned after using run().
- isAlive() : It can be used to check if the process is alive or has it ended.
- exitValue() : This can be used to make the process return an exit value. This will also block the external process until it ends. Exit value can be helpful in knowing if the process was successful.
- destroy() : This an be used to destroy the process. Just in case if there are some uncaught errors in the external process and it does not exit then by using destroy method we can destroy it ourselves. This way we won’t be waiting for the process to end infinitely.
That’s all about “How to execute Commands in Scala?”. I hope it was helpful and if you have any questions/feedback, please leave them in the comment section below.