/** This file contains functions for executing arbitrary programs in the operating system and returning their output. It uses Frink's Java introspection layers to call arbitrary Java methods. N.B.: All Java launching of external processes occurs through calling java.lang.Runtime.getRuntime().exec("cmd") which returns a java.lang.Process object which can be used to obtain an InputStream to capture the process's output. For more information on the methods of a Process object, see: https://docs.oracle.com/javase/8/docs/api/java/lang/Process.html In Java 1.5 and later, you may use java.lang.ProcessBuilder to construct and execute a Process, giving you more control over redirecting output and error streams. For more information on the methods of a ProcessBuilder object, see: https://docs.oracle.com/javase/8/docs/api/java/lang/ProcessBuilder.html */ /** This executes a command and returns all of its output as a single string. **/ execRead[cmd] := read[execInputStream[cmd]] /** This executes a command and returns all of its output as an enumerating expression that successively returns all the lines of its output. For example: for line = execLines["dir"] println[line] **/ execLines[cmd] := lines[execInputStream[cmd]] /** This executes a command and returns its InputStream. (That is, the output from the process.) You can then call the methods on the InputStream, or pass an InputStream to Frink functions like read[InputStream] or lines[InputStream] or "new image[InputStream]" The functions above will return the output in a Frink-friendly fashion. **/ execInputStream[cmd] := { // Execute the command to get a java.lang.Process object. proc = execProcess[cmd] // Get the input stream (the process's output) return proc.getInputStream[] } /** This is the rawest (and most flexible) way to start a process. It executes a command and returns a java.lang.Process object. This object can be used to get a java.io.InputStream (for reading the output of the process) or java.io.OutputStream (to send information to a running process), to wait for completion, or to destroy the process, or to read its exit value, etc. Other simplified functions above will handle simpler cases where you just want to try to launch a program and obtain its output. To see what all you can do with a Process object, see the Java documentation at: https://docs.oracle.com/javase/8/docs/api/java/lang/Process.html */ execProcess[cmd] := { // Use Java introspection to get the Runtime object which will be used to // create external processes. runtime = callJava["java.lang.Runtime", "getRuntime", [] ] // Execute the specified command. Note that there are other versions of // the Runtime.exec[] method which allow you to pass the working directory // and environment variables, if you need to. return runtime.exec[cmd] } "Processes.frink included ok"