On this page:
Subprocess
run
run_  shell
shell
Subprocess.in
Subprocess.out
Subprocess.err
Subprocess.maybe_  in
Subprocess.maybe_  out
Subprocess.maybe_  err
Subprocess.close
Subprocess.pid
Subprocess.wait
Subprocess.wait_  ok
Subprocess.poll
Subprocess.interrupt
Subprocess.kill
find_  executable_  path
current_  group_  new
current_  custodian_  mode
Subprocess.Pipe
Subprocess.Pipe.pipe
Subprocess.Error  Pipe
Subprocess.Error  Pipe.out
Subprocess.Group
Subprocess.Group.same
Subprocess.Group.new
Subprocess.New  Group
8.16.0.1

14.4 Subprocesses🔗ℹ

 import: rhombus/subprocess package: rhombus-lib

class

class subprocess.Subprocess():

  implements Closeable

  expression: ~error

Represents a subprocess created with functions like run and run_shell.

function

fun subprocess.run(

  program :: PathString,

  ~in: in :: Port.Input || Subprocess.Pipe = Port.Input.current(),

  ~out: out :: Port.Output || Subprocess.Pipe = Port.Output.current(),

  ~err: err :: Port.Output || Subprocess.ErrorPipe = Port.Output.current(),

  ~group: group :: Subprocess.Group || Subprocess.NewGroup

            = (if current_group_new() | #'new | #'same),

  arg :: PathString || ReadableString,

  ...

) :: Subprocess

Runs another program as a subprocess in the host operating system. The executable to run in the process is named by program, and it receives the args.

If program is a pathless file name (i.e., Path.parent(program) produces #'relative), then a non-#false result of find_executable_path(program) is used in place of program.

The new process’s input, output, or error output can be captured in a pipe using #'pipe for in, out, or err, respectively; the other end of the pipe is then accessible using Subprocess.in, Subprocess.out, or Subprocess.err, respectively. Otherwise, the new process’s input and output use the given ports, which default to the current ports. In the case of err, #'out is allowed to indicate that error output should use the same pipe or port as non-error output.

If group is #'same, the process group of the current process is used for the new subprocess. If group is #'new, the new subprocess is created in a fresh process group; the resulting Subprocess object then satisfies Subprocess.NewGroup. If group is a Subprocess.NewGroup, then the new subprocess is in the same group as that previously created subprocess.

When pipes are created for a subprocess, the local end of the pipe must be closed explicitly, perhaps using Subprocess.close. See also Closeable.let.

function

fun subprocess.run_shell(

  command :: String,

  ~in: in :: Port.Input || Subprocess.Pipe = Port.Input.current(),

  ~out: out :: Port.Output || Subprocess.Pipe = Port.Output.current(),

  ~err: err :: Port.Output || Subprocess.ErrorPipe = Port.Output.current(),

  ~group: group :: Subprocess.Group || Subprocess.NewGroup

            = (if current_group_new() | #'new | #'same)

) :: Subprocess

 

function

fun shell(command :: String) :: Boolean

The run_shell function is like run, but it runs a single shell command provided as a string, instead of running an executable with a list of individual arguments.

On Unix and Mac OS variants, "/bin/sh" is run as the shell. On Windows, "cmd.com" or "command.exe" is used.

The shell function is a shorthand to combine run_shell and Subprocess.wait_ok as run_shell(command).wait_ok().

property

property (subp :: subprocess.Subprocess).in

  :: Port.Output && Port.FileStream

 

property

property (subp :: subprocess.Subprocess).out

  :: Port.Input && Port.FileStream

 

property

property (subp :: subprocess.Subprocess).err

  :: Port.Input && Port.FileStream

 

property

property (subp :: subprocess.Subprocess).maybe_in

  :: maybe(Port.Output && Port.FileStream)

 

property

property (subp :: subprocess.Subprocess).maybe_out

  :: maybe(Port.Input && Port.FileStream)

 

property

property (subp :: subprocess.Subprocess).maybe_err

  :: maybe(Port.Input && Port.FileStream)

Accesses pipe ends created for subprocess.

Accessing the Subprocess.in, Subprocess.out, or Subprocess.err, property raises an exception if the subprocess does not have a pipe for the corresponding subprocess stream. Accessing the Subprocess.maybe_in, Subprocess.maybe_out, or Subprocess.maybe_err property either produces the same result as Subprocess.in, Subprocess.out, or Subprocess.err, or it returns #false.

method

method (subp :: subprocess.Subprocess).close() :: Void

Closes any pipes created for the subprocess that are still open.

property

property (subp :: subprocess.Subprocess).pid :: NonnegInt

Returns the operating system’s process ID for a subprocess.

method

method (subp :: subprocess.Subprocess).wait() :: Int

 

method

method (subp :: subprocess.Subprocess).wait_ok() :: Boolean

 

method

method (subp :: subprocess.Subprocess).poll() :: maybe(Int)

Waits for a subprocess to complete or checks whether it has completed.

The Subprocess.wait method waits for the subprocess and it returns its exit code. An exit code of 0 typically indicates success, and Subprocess.wait_ok(subp) is equivalent to Subprocess.wait(subp) == 0.

The Subprocess.poll method immediately returns #false if the subprocess has not completed, or it returns the same result as Subprocess.wait.

method

method (subp :: subprocess.Subprocess).interrupt() :: Void

 

method

method (subp :: subprocess.Subprocess).kill() :: Void

Send a process an interrupt signal or a kill signal, respectively. The latter cannot be ignored by a process.

function

fun subprocess.find_executable_path(program :: PathString)

  :: maybe(Path.Absolute)

Finds an absolute path for the executable named by program, returning #false if the path cannot be found or does not have executable permissions.

If program is a pathless name (i.e., Path.parent(program) produces #'relative), find_executable_path gets the value of the PATH environment variable; if this environment variable is defined, find_executable_path tries each path in PATH as a prefix for program. On Windows, the current directory is always implicitly the first item in PATH, so find_executable_path checks the current directory first on Windows. If the PATH environment variable is not defined or if program is not pathless, program is prefixed with the current directory.

On Windows, if program is not found and it has no file suffix, then the search starts over with ".exe" added to program, and the result is #false only if the path with ".exe" also cannot be found. The result includes the suffix ".exe" if only program with the suffix is found.

context parameter

Parameter.def subprocess.current_group_new

  :: Any.to_boolean

A context parameter that determines the default group for a subprocess. See Subprocess, run, and other subprocess-creation functions.

context parameter

Parameter.def subprocess.current_custodian_mode

  :: False || matching(#'kill) || matching(#'interrupt)

A context parameter that determines whether and how subprocesses are managed by a custodian.

enumeration

enum subprocess.Subprocess.Pipe:

  pipe

 

enumeration

enum subprocess.Subprocess.ErrorPipe:

  ~is_a Subprocess.Pipe

  out

 

enumeration

enum subprocess.Subprocess.Group:

  same

  new

 

annotation

subprocess.Subprocess.NewGroup

Port and group modes for use with Subprocess, run, shell, and run_shell.