Struct process::Command

Overview

This structure mimics the API of std::process::Command found in the standard library, but replaces functions that create a process with an asynchronous variant. The main provided asynchronous functions are spawn, status, and output.

Command uses asynchronous versions of some std types (for example Child).

Methods

fn new(command: String) -> Command

Constructs a new Command for launching the program at path program, with the following default configuration:

  • No arguments to the program
  • Inherit the current process's environment
  • Inherit the current process's working directory
  • Inherit stdin/stdout/stderr for spawn or status, but create pipes for output

Builder methods are provided to change these defaults and otherwise configure the process.

If program is not an absolute path, the PATH will be searched in an OS-defined way.

The search path to be used may be controlled by setting the PATH environment variable on the Command, but this has some implementation limitations on Windows (see issue rust-lang/rust#37519).

Examples

Basic usage:

use process::Command;
let command = Command::new("sh");
fn arg(self, arg: String)

Adds an argument to pass to the program.

Only one argument can be passed per use. So instead of:

use process::Command;

let command = Command::new("sh");
command.arg("-C /path/to/repo");

usage would be:

use process::Command;

let command = Command::new("sh");
command.arg("-C");
command.arg("/path/to/repo");

To pass multiple arguments see args.

Examples

Basic usage:

use process::Command;

let command = Command::new("ls");
command.arg("-l");
command.arg("-a");

let output = command.output().await?;
fn args(self, args: Vec)

Adds multiple arguments to pass to the program.

To pass a single argument see arg.

Examples

Basic usage:

use process::Command;

let command = Command::new("ls");
command.args(["-l", "-a"]);

let output = command.output().await?;
fn arg0(self, arg: String)

Sets executable argument.

Set the first process argument, argv[0], to something other than the default executable path.

fn stdin(self, stdio: Stdio)

Sets configuration for the child process's standard input (stdin) handle.

Defaults to inherit.

Examples

Basic usage:

use process::{Command, Stdio};

let command = Command::new("ls");
command.stdin(Stdio::null());

let output = command.output().await?;
fn stdout(self, stdio: Stdio)

Sets configuration for the child process's standard output (stdout) handle.

Defaults to inherit when used with spawn or status, and defaults to piped when used with output.

Examples

Basic usage:

use process::{Command, Stdio};

let command = Command::new("ls");
command.stdout(Stdio::null());

let output = command.output().await?;
fn stderr(self, stdio: Stdio)

Sets configuration for the child process's standard error (stderr) handle.

Defaults to inherit when used with spawn or status, and defaults to piped when used with output.

Examples

Basic usage:

use process::{Command, Stdio};

let command = Command::new("ls");
command.stderr(Stdio::null());

let output = command.output().await?;
fn kill_on_drop(self, kill_on_drop: bool)

Controls whether a kill operation should be invoked on a spawned child process when its corresponding Child handle is dropped.

By default, this value is assumed to be false, meaning the next spawned process will not be killed on drop, similar to the behavior of the standard library.

Caveats

On Unix platforms processes must be "reaped" by their parent process after they have exited in order to release all OS resources. A child process which has exited, but has not yet been reaped by its parent is considered a "zombie" process. Such processes continue to count against limits imposed by the system, and having too many zombie processes present can prevent additional processes from being spawned.

Although issuing a kill signal to the child process is a synchronous operation, the resulting zombie process cannot be .awaited inside of the destructor to avoid blocking other tasks. The tokio runtime will, on a best-effort basis, attempt to reap and clean up such processes in the background, but no additional guarantees are made with regard to how quickly or how often this procedure will take place.

If stronger guarantees are required, it is recommended to avoid dropping a Child handle where possible, and instead utilize child.wait().await or child.kill().await where possible.

fn spawn(self) -> Result

Executes the command as a child process, returning a handle to it.

By default, stdin, stdout and stderr are inherited from the parent.

This method will spawn the child process synchronously and return a handle to a future-aware child process. The Child returned implements Future itself to acquire the ExitStatus of the child, and otherwise the Child has methods to acquire handles to the stdin, stdout, and stderr streams.

All I/O this child does will be associated with the current default event loop.

Examples

Basic usage:

use process::Command;

async fn run_ls() {
   let command = Command::new("ls");
   command.spawn()?.wait().await?;
}

Caveats

Dropping/Cancellation

Similar to the behavior to the standard library, and unlike the futures paradigm of dropping-implies-cancellation, a spawned process will, by default, continue to execute even after the Child handle has been dropped.

The Command::kill_on_drop method can be used to modify this behavior and kill the child process if the Child wrapper is dropped before it has exited.

Unix Processes

On Unix platforms processes must be "reaped" by their parent process after they have exited in order to release all OS resources. A child process which has exited, but has not yet been reaped by its parent is considered a "zombie" process. Such processes continue to count against limits imposed by the system, and having too many zombie processes present can prevent additional processes from being spawned.

The tokio runtime will, on a best-effort basis, attempt to reap and clean up any process which it has spawned. No additional guarantees are made with regard to how quickly or how often this procedure will take place.

It is recommended to avoid dropping a Child process handle before it has been fully awaited if stricter cleanup guarantees are required.

Errors

On Unix platforms this method will fail with std::io::ErrorKind::WouldBlock if the system process limit is reached (which includes other applications running on the system).

Protocols

protocol DEBUG_FMT
format!("{:?}", value)

Allows the value to be debug printed.