Document the usage and methods of scala.sys.process.
From the first international scaladoc marathon. Contributed by: Daniel Sobral git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@25599 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
parent
0b2544fa4b
commit
47d321c78e
|
@ -14,6 +14,12 @@ import java.io.{ BufferedReader, InputStreamReader, FilterInputStream, FilterOut
|
|||
import java.util.concurrent.LinkedBlockingQueue
|
||||
import scala.collection.immutable.Stream
|
||||
|
||||
/**
|
||||
* This object contains factories for [[scala.sys.process.ProcessIO]],
|
||||
* which can be used to control the I/O of a [[scala.sys.process.Process]]
|
||||
* when a [[scala.sys.process.ProcessBuilder]] is started with the `run`
|
||||
* command.
|
||||
*/
|
||||
object BasicIO {
|
||||
final val BufferSize = 8192
|
||||
final val Newline = props("line.separator")
|
||||
|
|
|
@ -14,6 +14,19 @@ import ProcessBuilder._
|
|||
|
||||
/** Represents a process that is running or has finished running.
|
||||
* It may be a compound process with several underlying native processes (such as 'a #&& b`).
|
||||
*
|
||||
* This trait is often not used directly, though its companion object contains
|
||||
* factories for [[scala.sys.process.ProcessBuilder]], the main component of this
|
||||
* package.
|
||||
*
|
||||
* It is used directly when calling the method `run` on a `ProcessBuilder`,
|
||||
* which makes the process run in the background. The methods provided on `Process`
|
||||
* make it possible for one to block until the process exits and get the exit value,
|
||||
* or destroy the process altogether.
|
||||
*
|
||||
* Presently, one cannot poll the `Process` to see if it has finished.
|
||||
*
|
||||
* @see [[scala.sys.process.ProcessBuilder]]
|
||||
*/
|
||||
trait Process {
|
||||
/** Blocks until this process exits and returns the exit code.*/
|
||||
|
@ -25,20 +38,52 @@ trait Process {
|
|||
/** Methods for constructing simple commands that can then be combined. */
|
||||
object Process extends ProcessImpl with ProcessCreation { }
|
||||
|
||||
/** Factories for creating [[scala.sys.process.ProcessBuilder]]. They can be
|
||||
* found on and used through [[scala.sys.process.Process]]'s companion object.
|
||||
*/
|
||||
trait ProcessCreation {
|
||||
/** Create a [[scala.sys.process.ProcessBuilder]] from a `String`, including the
|
||||
* parameters.
|
||||
*
|
||||
* @example {{{ apply("cat file.txt") }}}
|
||||
*/
|
||||
def apply(command: String): ProcessBuilder = apply(command, None)
|
||||
|
||||
/** Create a [[scala.sys.process.ProcessBuilder]] from a sequence of `String`,
|
||||
* where the head is the command and each element of the tail is a parameter.
|
||||
*
|
||||
* @example {{{ apply("cat" :: files) }}}
|
||||
*/
|
||||
def apply(command: Seq[String]): ProcessBuilder = apply(command, None)
|
||||
|
||||
/** Create a [[scala.sys.process.ProcessBuilder]] from a command represented by a `String`,
|
||||
* and a sequence of `String` representing the arguments.
|
||||
*
|
||||
* @example {{{ apply("cat", files) }}}
|
||||
*/
|
||||
def apply(command: String, arguments: Seq[String]): ProcessBuilder = apply(command +: arguments, None)
|
||||
|
||||
/** create ProcessBuilder with working dir set to File and extra environment variables */
|
||||
/** Create a [[scala.sys.process.ProcessBuilder]] with working dir set to `File` and extra
|
||||
* environment variables.
|
||||
*
|
||||
* @example {{{ apply("java", new java.ioFile("/opt/app"), "CLASSPATH" -> "library.jar") }}}
|
||||
*/
|
||||
def apply(command: String, cwd: File, extraEnv: (String, String)*): ProcessBuilder =
|
||||
apply(command, Some(cwd), extraEnv: _*)
|
||||
|
||||
/** create ProcessBuilder with working dir set to File and extra environment variables */
|
||||
/** Create a [[scala.sys.process.ProcessBuilder]] with working dir set to `File` and extra
|
||||
* environment variables.
|
||||
*
|
||||
* @example {{{ apply("java" :: javaArgs, new java.ioFile("/opt/app"), "CLASSPATH" -> "library.jar") }}}
|
||||
*/
|
||||
def apply(command: Seq[String], cwd: File, extraEnv: (String, String)*): ProcessBuilder =
|
||||
apply(command, Some(cwd), extraEnv: _*)
|
||||
|
||||
/** create ProcessBuilder with working dir optionally set to File and extra environment variables */
|
||||
/** Create a [[scala.sys.process.ProcessBuilder]] with working dir optionally set to
|
||||
* `File` and extra environment variables.
|
||||
*
|
||||
* @example {{{ apply("java", params.get("cwd"), "CLASSPATH" -> "library.jar") }}}
|
||||
*/
|
||||
def apply(command: String, cwd: Option[File], extraEnv: (String, String)*): ProcessBuilder = {
|
||||
apply(command.split("""\s+"""), cwd, extraEnv : _*)
|
||||
// not smart to use this on windows, because CommandParser uses \ to escape ".
|
||||
|
@ -48,7 +93,11 @@ trait ProcessCreation {
|
|||
}*/
|
||||
}
|
||||
|
||||
/** create ProcessBuilder with working dir optionally set to File and extra environment variables */
|
||||
/** Create a [[scala.sys.process.ProcessBuilder]] with working dir optionally set to
|
||||
* `File` and extra environment variables.
|
||||
*
|
||||
* @example {{{ apply("java" :: javaArgs, params.get("cwd"), "CLASSPATH" -> "library.jar") }}}
|
||||
*/
|
||||
def apply(command: Seq[String], cwd: Option[File], extraEnv: (String, String)*): ProcessBuilder = {
|
||||
val jpb = new JProcessBuilder(command.toArray: _*)
|
||||
cwd foreach (jpb directory _)
|
||||
|
@ -56,30 +105,111 @@ trait ProcessCreation {
|
|||
apply(jpb)
|
||||
}
|
||||
|
||||
/** create a [[scala.sys.process.ProcessBuilder]] from a `java.lang.ProcessBuilder`.
|
||||
*
|
||||
* @example {{{
|
||||
* apply((new java.lang.ProcessBuilder("ls", "-l")) directory new java.io.File(System.getProperty("user.home")))
|
||||
* }}}
|
||||
*/
|
||||
def apply(builder: JProcessBuilder): ProcessBuilder = new Simple(builder)
|
||||
|
||||
/** create a [[scala.sys.process.ProcessBuilder]] from a `java.io.File`. This
|
||||
* `ProcessBuilder` can then be used as a `Source` or a `Sink`, so one can
|
||||
* pipe things from and to it.
|
||||
*/
|
||||
def apply(file: File): FileBuilder = new FileImpl(file)
|
||||
|
||||
/** Create a [[scala.sys.process.ProcessBuilder]] from a `java.net.URL`. This
|
||||
* `ProcessBuilder` can then be used as a `Source`, so that one can pipe things
|
||||
* from it.
|
||||
*/
|
||||
def apply(url: URL): URLBuilder = new URLImpl(url)
|
||||
|
||||
/** Create a [[scala.sys.process.ProcessBuilder]] from a Scala XML Element.
|
||||
* This can be used as a way to template strings.
|
||||
*
|
||||
* @example {{{
|
||||
* apply(<x> {dxPath.absolutePath} --dex --output={classesDexPath.absolutePath} {classesMinJarPath.absolutePath}</x>)
|
||||
* }}}
|
||||
*/
|
||||
def apply(command: scala.xml.Elem): ProcessBuilder = apply(command.text.trim)
|
||||
|
||||
/** Create a [[scala.sys.process.ProcessBuilder]] from a `Boolean`. This can be
|
||||
* to force an exit value.
|
||||
*/
|
||||
def apply(value: Boolean): ProcessBuilder = apply(value.toString, if (value) 0 else 1)
|
||||
|
||||
/** Create a [[scala.sys.process.ProcessBuilder]] from a `String` name and a
|
||||
* `Boolean`. This can be used to force an exit value, with the name being
|
||||
* used for `toString`.
|
||||
*/
|
||||
def apply(name: String, exitValue: => Int): ProcessBuilder = new Dummy(name, exitValue)
|
||||
|
||||
/** Create a sequence of [[scala.sys.process.ProcessBuilder.Source]] from a sequence of
|
||||
* something else for which there's an implicit conversion to `Source`.
|
||||
*/
|
||||
def applySeq[T](builders: Seq[T])(implicit convert: T => Source): Seq[Source] = builders.map(convert)
|
||||
|
||||
/** Create a [[scala.sys.process.ProcessBuilder]] from one or more
|
||||
* [[scala.sys.process.ProcessBuilder.Source]], which can then be
|
||||
* piped to something else.
|
||||
*
|
||||
* This will concatenate the output of all sources.
|
||||
*/
|
||||
def cat(file: Source, files: Source*): ProcessBuilder = cat(file +: files)
|
||||
|
||||
/** Create a [[scala.sys.process.ProcessBuilder]] from a non-empty sequence
|
||||
* of [[scala.sys.process.ProcessBuilder.Source]], which can then be
|
||||
* piped to something else.
|
||||
*
|
||||
* This will concatenate the output of all sources. For example:
|
||||
*
|
||||
* {{{
|
||||
* import scala.sys.process._
|
||||
* import scala.sys.process.Process.cat
|
||||
* import java.net.URL
|
||||
* import java.io.File
|
||||
*
|
||||
* val spde = new URL("http://technically.us/spde/About")
|
||||
* val dispatch = new URL("http://databinder.net/dispatch/About")
|
||||
* val build = new File("project/build.properties")
|
||||
* cat(spde, dispatch, build) #| "grep -i scala" !
|
||||
* }}}
|
||||
*/
|
||||
def cat(files: Seq[Source]): ProcessBuilder = {
|
||||
require(files.nonEmpty)
|
||||
files map (_.cat) reduceLeft (_ #&& _)
|
||||
}
|
||||
}
|
||||
|
||||
/** Provide implicit conversions for the factories offered by [[scala.sys.process.Process]]'s
|
||||
* companion object. These implicits can then be used to decrease the noise in a pipeline
|
||||
* of commands, making it look more shell-like. They are available through the package object
|
||||
* [[scala.sys.process]].
|
||||
*/
|
||||
trait ProcessImplicits {
|
||||
import Process._
|
||||
|
||||
/** Return a sequence of [[scala.sys.process.ProcessBuilder.Source]] from a sequence
|
||||
* of values for which an implicit conversion to `Source` is available.
|
||||
*/
|
||||
implicit def buildersToProcess[T](builders: Seq[T])(implicit convert: T => Source): Seq[Source] = applySeq(builders)
|
||||
|
||||
/** Implicitly convert a `java.lang.ProcessBuilder` into a Scala one. */
|
||||
implicit def builderToProcess(builder: JProcessBuilder): ProcessBuilder = apply(builder)
|
||||
|
||||
/** Implicitly convert a `java.io.File` into a [[scala.sys.process.ProcessBuilder]] */
|
||||
implicit def fileToProcess(file: File): FileBuilder = apply(file)
|
||||
|
||||
/** Implicitly convert a `java.net.URL` into a [[scala.sys.process.ProcessBuilder]] */
|
||||
implicit def urlToProcess(url: URL): URLBuilder = apply(url)
|
||||
|
||||
/** Implicitly convert a [[scala.xml.Elem]] into a [[scala.sys.process.ProcessBuilder]] */
|
||||
implicit def xmlToProcess(command: scala.xml.Elem): ProcessBuilder = apply(command)
|
||||
|
||||
/** Implicitly convert a `String` into a [[scala.sys.process.ProcessBuilder]] */
|
||||
implicit def stringToProcess(command: String): ProcessBuilder = apply(command)
|
||||
|
||||
/** Implicitly convert a sequence of `String` into a [[scala.sys.process.ProcessBuilder]] */
|
||||
implicit def stringSeqToProcess(command: Seq[String]): ProcessBuilder = apply(command)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,66 @@ package process
|
|||
import processInternal._
|
||||
import ProcessBuilder._
|
||||
|
||||
/** Represents a runnable process. */
|
||||
/** Represents a runnable process.
|
||||
*
|
||||
* This is the main component of this package. A `ProcessBuilder` may be composed with
|
||||
* others, either concatenating their outputs or piping them from one to the next, and
|
||||
* possibly with conditional execution depending on the last process exit value.
|
||||
*
|
||||
* Once executed, one can retrieve the output or redirect it to a
|
||||
* [[scala.sys.process.ProcessLogger]], or one can get the exit value, discarding or
|
||||
* redirecting the output.
|
||||
*
|
||||
* One creates a `ProcessBuilder` through factories provided in [[scala.sys.process.Process]]'s
|
||||
* companion object, or implicit conversions based on these factories made available in the
|
||||
* package object [[scala.sys.process]].
|
||||
*
|
||||
* Let's examine in detail one example of usage:
|
||||
*
|
||||
* {{{
|
||||
* import scala.sys.process._
|
||||
* "find src -name *.scala -exec grep null {} ;" #| "xargs test -z" #&& "echo null-free" #|| "echo null detected" !
|
||||
* }}}
|
||||
*
|
||||
* Note that every `String` is implicitly converted into a `ProcessBuilder`
|
||||
* through the implicits imported from [[scala.sys.process]]. These `ProcessBuilder` are then
|
||||
* combined in three different ways.
|
||||
*
|
||||
* 1. `#|` pipes the output of the first command into the input of the second command. It
|
||||
* mirrors a shell pipe (`|`).
|
||||
* 2. `#&&` conditionally executes the second command if the previous one finished with
|
||||
* exit value 0. It mirrors shell's `&&`.
|
||||
* 3. `#||` conditionally executes the third command if the exit value of the previous
|
||||
* command is is different than zero. It mirrors shell's `&&`.
|
||||
*
|
||||
* Not shown here, the equivalent of a shell's `;` would be `###`. The reason for this name is
|
||||
* that `;` is a reserved token in Scala.
|
||||
*
|
||||
* Finally, `!` at the end executes the commands, and returns the exit value. If the output
|
||||
* was desired instead, one could run that with `!!` instead.
|
||||
*
|
||||
* If one wishes to execute the commands in background, one can either call `run`, which
|
||||
* returns a [[scala.sys.process.Process]] from which the exit value can be obtained, or
|
||||
* `lines`, which returns a [scala.collection.immutable.Stream] of output lines. This throws
|
||||
* an exception at the end of the `Stream` is the exit value is non-zero. To avoid exceptions,
|
||||
* one can use `lines_!` instead.
|
||||
*
|
||||
* One can also start the commands in specific ways to further control their I/O. Using `!<` to
|
||||
* start the commands will use the stdin from the current process for them. All methods can
|
||||
* be used passing a [[scala.sys.process.ProcessLogger]] to capture the output, both stderr and
|
||||
* stdout. And, when using `run`, one can pass a [[scala.sys.process.ProcessIO]] to control
|
||||
* stdin, stdout and stderr.
|
||||
*
|
||||
* The stdin of a command can be redirected from a `java.io.InputStream`, a `java.io.File`, a
|
||||
* `java.net.URL` or another `ProcessBuilder` through the method `#<`. Likewise, the stdout
|
||||
* can be sent to a `java.io.OutputStream`, a `java.io.File` or another `ProcessBuilder` with
|
||||
* the method `#>`. The method `#>>` can be used to append the output to a `java.io.File`.
|
||||
* For example:
|
||||
*
|
||||
* {{{
|
||||
* new URL("http://databinder.net/dispatch/About") #> "grep JSON" #>> new File("About_JSON") !
|
||||
* }}}
|
||||
*/
|
||||
trait ProcessBuilder extends Source with Sink {
|
||||
/** Starts the process represented by this builder, blocks until it exits, and returns the output as a String. Standard error is
|
||||
* sent to the console. If the exit code is non-zero, an exception is thrown.*/
|
||||
|
@ -83,40 +142,75 @@ trait ProcessBuilder extends Source with Sink {
|
|||
def hasExitValue: Boolean
|
||||
}
|
||||
|
||||
/** This object contains traits used to describe input and output sources. */
|
||||
object ProcessBuilder extends ProcessBuilderImpl {
|
||||
/** Used when creating [[scala.sys.process.ProcessBuilder.Source]] from an URL. */
|
||||
trait URLBuilder extends Source {
|
||||
|
||||
}
|
||||
|
||||
/** Used when creating [[scala.sys.process.ProcessBuilder.Source]] and/or
|
||||
* [[scala.sys.process.ProcessBuilder.Sink]] from a file.
|
||||
*/
|
||||
trait FileBuilder extends Sink with Source {
|
||||
/** Append the contents of a `java.io.File` to this file */
|
||||
def #<<(f: File): ProcessBuilder
|
||||
|
||||
/** Append the contents from a `java.net.URL` to this file */
|
||||
def #<<(u: URL): ProcessBuilder
|
||||
|
||||
/** Append the contents of a `java.io.InputStream` to this file */
|
||||
def #<<(i: => InputStream): ProcessBuilder
|
||||
|
||||
/** Append the contents of a [[scala.sys.process.ProcessBuilder]] to this file */
|
||||
def #<<(p: ProcessBuilder): ProcessBuilder
|
||||
}
|
||||
|
||||
/** Represents everything that can be used as an input to a
|
||||
* [[scala.sys.process.ProcessBuilder]].
|
||||
*/
|
||||
trait Source {
|
||||
protected def toSource: ProcessBuilder
|
||||
|
||||
/** Writes the output stream of this process to the given file. */
|
||||
def #> (f: File): ProcessBuilder = toFile(f, false)
|
||||
|
||||
/** Appends the output stream of this process to the given file. */
|
||||
def #>> (f: File): ProcessBuilder = toFile(f, true)
|
||||
|
||||
/** Writes the output stream of this process to the given OutputStream. The
|
||||
* argument is call-by-name, so the stream is recreated, written, and closed each
|
||||
* time this process is executed. */
|
||||
* argument is call-by-name, so the stream is recreated, written, and closed each
|
||||
* time this process is executed.
|
||||
*/
|
||||
def #>(out: => OutputStream): ProcessBuilder = #> (new OStreamBuilder(out, "<output stream>"))
|
||||
|
||||
/** Writes the output stream of this process to a [[scala.sys.process.ProcessBuilder]]. */
|
||||
def #>(b: ProcessBuilder): ProcessBuilder = new PipedBuilder(toSource, b, false)
|
||||
|
||||
/** Returnes a [[scala.sys.process.ProcessBuilder]] representing this `Source`. */
|
||||
def cat = toSource
|
||||
private def toFile(f: File, append: Boolean) = #> (new FileOutput(f, append))
|
||||
}
|
||||
|
||||
/** Represents everything that can receive an output from a
|
||||
* [[scala.sys.process.ProcessBuilder]].
|
||||
*/
|
||||
trait Sink {
|
||||
protected def toSink: ProcessBuilder
|
||||
|
||||
/** Reads the given file into the input stream of this process. */
|
||||
def #< (f: File): ProcessBuilder = #< (new FileInput(f))
|
||||
|
||||
/** Reads the given URL into the input stream of this process. */
|
||||
def #< (f: URL): ProcessBuilder = #< (new URLInput(f))
|
||||
|
||||
/** Reads the given InputStream into the input stream of this process. The
|
||||
* argument is call-by-name, so the stream is recreated, read, and closed each
|
||||
* time this process is executed. */
|
||||
* argument is call-by-name, so the stream is recreated, read, and closed each
|
||||
* time this process is executed.
|
||||
*/
|
||||
def #<(in: => InputStream): ProcessBuilder = #< (new IStreamBuilder(in, "<input stream>"))
|
||||
|
||||
/** Reads the output of a [[scala.sys.process.ProcessBuilder]] into the input stream of this process. */
|
||||
def #<(b: ProcessBuilder): ProcessBuilder = new PipedBuilder(b, toSink, false)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,12 @@ package process
|
|||
|
||||
import processInternal._
|
||||
|
||||
/** Each method will be called in a separate thread.
|
||||
/** This class is used to control the I/O of every [[scala.sys.process.ProcessBuilder]].
|
||||
* Most of the time, there is no need to interact with `ProcessIO` directly. However, if
|
||||
* fine control over the I/O of a `ProcessBuilder` is desired, one can use the factories
|
||||
* on [[scala.sys.process.BasicIO]] stand-alone object to create one.
|
||||
*
|
||||
* Each method will be called in a separate thread.
|
||||
* If daemonizeThreads is true, they will all be marked daemon threads.
|
||||
*/
|
||||
final class ProcessIO(
|
||||
|
|
|
@ -39,6 +39,7 @@ trait ProcessLogger {
|
|||
def buffer[T](f: => T): T
|
||||
}
|
||||
|
||||
/** A [[scala.sys.process.ProcessLogger]] that writes output to a file. */
|
||||
class FileProcessLogger(file: File) extends ProcessLogger with Closeable with Flushable {
|
||||
private val writer = (
|
||||
new PrintWriter(
|
||||
|
@ -56,9 +57,26 @@ class FileProcessLogger(file: File) extends ProcessLogger with Closeable with Fl
|
|||
def flush(): Unit = writer.flush()
|
||||
}
|
||||
|
||||
/** Provides factories to create [[scala.sys.process.ProcessLogger]], which
|
||||
* are used to capture output of [[scala.sys.process.ProcessBuilder]] commands
|
||||
* when run.
|
||||
*/
|
||||
object ProcessLogger {
|
||||
/** Creates a [[scala.sys.process.ProcessLogger]] that redirects output to a `java.io.File`. */
|
||||
def apply(file: File): FileProcessLogger = new FileProcessLogger(file)
|
||||
|
||||
/** Creates a [[scala.sys.process.ProcessLogger]] that sends all output, standard and error,
|
||||
* to the passed function.
|
||||
*/
|
||||
def apply(fn: String => Unit): ProcessLogger = apply(fn, fn)
|
||||
|
||||
/** Creates a [[scala.sys.process.ProcessLogger]] that sends all output to the corresponding
|
||||
* function.
|
||||
*
|
||||
* @param fout This function will receive standard outpout.
|
||||
*
|
||||
* @param ferr This function will receive standard error.
|
||||
*/
|
||||
def apply(fout: String => Unit, ferr: String => Unit): ProcessLogger =
|
||||
new ProcessLogger {
|
||||
def out(s: => String): Unit = fout(s)
|
||||
|
|
|
@ -11,6 +11,58 @@
|
|||
// for process debugging output.
|
||||
//
|
||||
package scala.sys {
|
||||
/**
|
||||
* This package is used to create process pipelines, similar to Unix command pipelines.
|
||||
*
|
||||
* The key concept is that one builds a [[scala.sys.process.Process]] that will run and return an exit
|
||||
* value. This `Process` is usually composed of one or more [[scala.sys.process.ProcessBuilder]], fed by a
|
||||
* [[scala.sys.process.ProcessBuilder.Source]] and feeding a [[scala.sys.process.ProcessBuilder.Sink]]. A
|
||||
* `ProcessBuilder` itself is both a `Source` and a `Sink`.
|
||||
*
|
||||
* As `ProcessBuilder`, `Sink` and `Source` are abstract, one usually creates them with `apply` methods on
|
||||
* the companion object of [[scala.sys.process.Process]], or through implicit conversions available in this
|
||||
* package object from `String` and other types. The pipe is composed through unix-like pipeline and I/O
|
||||
* redirection operators available on [[scala.sys.process.ProcessBuilder]].
|
||||
*
|
||||
* The example below shows how to build and combine such commands. It searches for `null` uses in the `src`
|
||||
* directory, printing a message indicating whether they were found or not. The first command pipes its
|
||||
* output to the second command, whose exit value is then used to choose between the third or fourth
|
||||
* commands. This same example is explained in greater detail on [[scala.sys.process.ProcessBuilder]].
|
||||
*
|
||||
* {{{
|
||||
* import scala.sys.process._
|
||||
* (
|
||||
* "find src -name *.scala -exec grep null {} ;"
|
||||
* #| "xargs test -z"
|
||||
* #&& "echo null-free" #|| "echo null detected"
|
||||
* ) !
|
||||
* }}}
|
||||
*
|
||||
* Other implicits available here are for [[scala.sys.process.ProcessBuilder.FileBuilder]], which extends
|
||||
* both `Sink` and `Source`, and for [[scala.sys.process.ProcessBuilder.URLBuilder]], which extends
|
||||
* `Source` alone.
|
||||
*
|
||||
* One can even create a `Process` solely out of these, without running any command. For example, this will
|
||||
* download from a URL to a file:
|
||||
*
|
||||
* {{{
|
||||
* import java.io.File
|
||||
* import scala.sys.process._
|
||||
* new File("About.html") #> new File("About_copy.html") !
|
||||
* }}}
|
||||
*
|
||||
* One may use a `Process` directly through `ProcessBuilder`'s `run` method, which starts the process in
|
||||
* the background, and returns a `Process`. If background execution is not desired, one can get a
|
||||
* `ProcessBuilder` to execute through a method such as `!`, `lines`, `run` or variations thereof. That
|
||||
* will create the `Process` to execute the commands, and return either the exit value or the output, maybe
|
||||
* throwing an exception.
|
||||
*
|
||||
* Finally, when executing a `ProcessBuilder`, one may pass a [[scala.sys.process.ProcessLogger]] to
|
||||
* capture stdout and stderr of the executing processes. A `ProcessLogger` may be created through its
|
||||
* companion object from functions of type `(String) => Unit`, or one might redirect it to a file, using
|
||||
* [[scala.sys.process.FileProcessLogger]], which can also be created through `ProcessLogger`'s object
|
||||
* companion.
|
||||
*/
|
||||
package object process extends ProcessImplicits {
|
||||
def javaVmArguments: List[String] = {
|
||||
import collection.JavaConversions._
|
||||
|
|
Loading…
Reference in New Issue