Struct Command

struct Command { ... }

A process builder, providing fine-grained control over how a new process should be spawned.

A default configuration can be generated using Command::new(program), where program gives a path to the program to be executed. Additional builder methods allow the configuration to be changed (for example, by adding arguments) prior to spawning:

# if cfg!(not(all(target_vendor = "apple", not(target_os = "macos")))) {
use std::process::Command;

let output = if cfg!(target_os = "windows") {
    Command::new("cmd")
        .args(["/C", "echo hello"])
        .output()
        .expect("failed to execute process")
} else {
    Command::new("sh")
        .arg("-c")
        .arg("echo hello")
        .output()
        .expect("failed to execute process")
};

let hello = output.stdout;
# }

Command can be reused to spawn multiple processes. The builder methods change the command without needing to immediately spawn the process.

use std::process::Command;

let mut echo_hello = Command::new("sh");
echo_hello.arg("-c").arg("echo hello");
let hello_1 = echo_hello.output().expect("failed to execute process");
let hello_2 = echo_hello.output().expect("failed to execute process");

Similarly, you can call builder methods after spawning a process and then spawn a new process with the modified settings.

use std::process::Command;

let mut list_dir = Command::new("ls");

// Execute `ls` in the current directory of the program.
list_dir.status().expect("process failed to execute");

println!();

// Change `ls` to execute in the root directory.
list_dir.current_dir("/");

// And then execute `ls` again but in the root directory.
list_dir.status().expect("process failed to execute");

Implementations

impl Command

fn new<S: AsRef<OsStr>>(program: S) -> 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 #37519).

Platform-specific behavior

Note on Windows: For executable files with the .exe extension, it can be omitted when specifying the program for this Command. However, if the file has a different extension, a filename including the extension needs to be provided, otherwise the file won't be found.

Examples

use std::process::Command;

Command::new("sh")
    .spawn()
    .expect("sh command failed to start");

Caveats

Command::new is only intended to accept the path of the program. If you pass a program path along with arguments like Command::new("ls -l").spawn(), it will try to search for ls -l literally. The arguments need to be passed separately, such as via arg or args.

use std::process::Command;

Command::new("ls")
    .arg("-l") // arg passed separately
    .spawn()
    .expect("ls command failed to start");
fn arg<S: AsRef<OsStr>>(self: &mut Self, arg: S) -> &mut Command

Adds an argument to pass to the program.

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

# std::process::Command::new("sh")
.arg("-C /path/to/repo")
# ;

usage would be:

# std::process::Command::new("sh")
.arg("-C")
.arg("/path/to/repo")
# ;

To pass multiple arguments see args.

Note that the argument is not passed through a shell, but given literally to the program. This means that shell syntax like quotes, escaped characters, word splitting, glob patterns, variable substitution, etc. have no effect.

On Windows, use caution with untrusted inputs. Most applications use the standard convention for decoding arguments passed to them. These are safe to use with arg. However, some applications such as cmd.exe and .bat files use a non-standard way of decoding arguments. They are therefore vulnerable to malicious input.

In the case of cmd.exe this is especially important because a malicious argument can potentially run arbitrary shell commands.

See Windows argument splitting for more details or raw_arg for manually implementing non-standard argument encoding.

Examples

use std::process::Command;

Command::new("ls")
    .arg("-l")
    .arg("-a")
    .spawn()
    .expect("ls command failed to start");
fn args<I, S>(self: &mut Self, args: I) -> &mut Command
where
    I: IntoIterator<Item = S>,
    S: AsRef<OsStr>

Adds multiple arguments to pass to the program.

To pass a single argument see arg.

Note that the arguments are not passed through a shell, but given literally to the program. This means that shell syntax like quotes, escaped characters, word splitting, glob patterns, variable substitution, etc. have no effect.

On Windows, use caution with untrusted inputs. Most applications use the standard convention for decoding arguments passed to them. These are safe to use with arg. However, some applications such as cmd.exe and .bat files use a non-standard way of decoding arguments. They are therefore vulnerable to malicious input.

In the case of cmd.exe this is especially important because a malicious argument can potentially run arbitrary shell commands.

See Windows argument splitting for more details or raw_arg for manually implementing non-standard argument encoding.

Examples

use std::process::Command;

Command::new("ls")
    .args(["-l", "-a"])
    .spawn()
    .expect("ls command failed to start");
fn env<K, V>(self: &mut Self, key: K, val: V) -> &mut Command
where
    K: AsRef<OsStr>,
    V: AsRef<OsStr>

Inserts or updates an explicit environment variable mapping.

This method allows you to add an environment variable mapping to the spawned process or overwrite a previously set value. You can use Command::envs to set multiple environment variables simultaneously.

Child processes will inherit environment variables from their parent process by default. Environment variables explicitly set using Command::env take precedence over inherited variables. You can disable environment variable inheritance entirely using Command::env_clear or for a single key using Command::env_remove.

Note that environment variable names are case-insensitive (but case-preserving) on Windows and case-sensitive on all other platforms.

Examples

use std::process::Command;

Command::new("ls")
    .env("PATH", "/bin")
    .spawn()
    .expect("ls command failed to start");
fn envs<I, K, V>(self: &mut Self, vars: I) -> &mut Command
where
    I: IntoIterator<Item = (K, V)>,
    K: AsRef<OsStr>,
    V: AsRef<OsStr>

Inserts or updates multiple explicit environment variable mappings.

This method allows you to add multiple environment variable mappings to the spawned process or overwrite previously set values. You can use Command::env to set a single environment variable.

Child processes will inherit environment variables from their parent process by default. Environment variables explicitly set using Command::envs take precedence over inherited variables. You can disable environment variable inheritance entirely using Command::env_clear or for a single key using Command::env_remove.

Note that environment variable names are case-insensitive (but case-preserving) on Windows and case-sensitive on all other platforms.

Examples

use std::process::{Command, Stdio};
use std::env;
use std::collections::HashMap;

let filtered_env : HashMap<String, String> =
    env::vars().filter(|&(ref k, _)|
        k == "TERM" || k == "TZ" || k == "LANG" || k == "PATH"
    ).collect();

Command::new("printenv")
    .stdin(Stdio::null())
    .stdout(Stdio::inherit())
    .env_clear()
    .envs(&filtered_env)
    .spawn()
    .expect("printenv failed to start");
fn env_remove<K: AsRef<OsStr>>(self: &mut Self, key: K) -> &mut Command

Removes an explicitly set environment variable and prevents inheriting it from a parent process.

This method will remove the explicit value of an environment variable set via Command::env or Command::envs. In addition, it will prevent the spawned child process from inheriting that environment variable from its parent process.

After calling Command::env_remove, the value associated with its key from Command::get_envs will be None.

To clear all explicitly set environment variables and disable all environment variable inheritance, you can use Command::env_clear.

Examples

Prevent any inherited GIT_DIR variable from changing the target of the git command, while allowing all other variables, like GIT_AUTHOR_NAME.

use std::process::Command;

Command::new("git")
    .arg("commit")
    .env_remove("GIT_DIR")
    .spawn()?;
# std::io::Result::Ok(())
fn env_clear(self: &mut Self) -> &mut Command

Clears all explicitly set environment variables and prevents inheriting any parent process environment variables.

This method will remove all explicitly added environment variables set via Command::env or Command::envs. In addition, it will prevent the spawned child process from inheriting any environment variable from its parent process.

After calling Command::env_clear, the iterator from Command::get_envs will be empty.

You can use Command::env_remove to clear a single mapping.

Examples

The behavior of sort is affected by LANG and LC_* environment variables. Clearing the environment makes sort's behavior independent of the parent processes' language.

use std::process::Command;

Command::new("sort")
    .arg("file.txt")
    .env_clear()
    .spawn()?;
# std::io::Result::Ok(())
fn current_dir<P: AsRef<Path>>(self: &mut Self, dir: P) -> &mut Command

Sets the working directory for the child process.

Platform-specific behavior

If the program path is relative (e.g., "./script.sh"), it's ambiguous whether it should be interpreted relative to the parent's working directory or relative to current_dir. The behavior in this case is platform specific and unstable, and it's recommended to use canonicalize to get an absolute program path instead.

Examples

use std::process::Command;

Command::new("ls")
    .current_dir("/bin")
    .spawn()
    .expect("ls command failed to start");
fn stdin<T: Into<Stdio>>(self: &mut Self, cfg: T) -> &mut Command

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

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

Examples

use std::process::{Command, Stdio};

Command::new("ls")
    .stdin(Stdio::null())
    .spawn()
    .expect("ls command failed to start");
fn stdout<T: Into<Stdio>>(self: &mut Self, cfg: T) -> &mut Command

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

use std::process::{Command, Stdio};

Command::new("ls")
    .stdout(Stdio::null())
    .spawn()
    .expect("ls command failed to start");
fn stderr<T: Into<Stdio>>(self: &mut Self, cfg: T) -> &mut Command

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

use std::process::{Command, Stdio};

Command::new("ls")
    .stderr(Stdio::null())
    .spawn()
    .expect("ls command failed to start");
fn spawn(self: &mut Self) -> io::Result<Child>

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

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

Examples

use std::process::Command;

Command::new("ls")
    .spawn()
    .expect("ls command failed to start");
fn output(self: &mut Self) -> io::Result<Output>

Executes the command as a child process, waiting for it to finish and collecting all of its output.

By default, stdout and stderr are captured (and used to provide the resulting output). Stdin is not inherited from the parent and any attempt by the child process to read from the stdin stream will result in the stream immediately closing.

Examples

use std::process::Command;
use std::io::{self, Write};
let output = Command::new("/bin/cat")
    .arg("file.txt")
    .output()?;

println!("status: {}", output.status);
io::stdout().write_all(&output.stdout)?;
io::stderr().write_all(&output.stderr)?;

assert!(output.status.success());
# io::Result::Ok(())
fn status(self: &mut Self) -> io::Result<ExitStatus>

Executes a command as a child process, waiting for it to finish and collecting its status.

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

Examples

use std::process::Command;

let status = Command::new("/bin/cat")
    .arg("file.txt")
    .status()
    .expect("failed to execute process");

println!("process finished with: {status}");

assert!(status.success());
fn get_program(self: &Self) -> &OsStr

Returns the path to the program that was given to Command::new.

Examples

use std::process::Command;

let cmd = Command::new("echo");
assert_eq!(cmd.get_program(), "echo");
fn get_args(self: &Self) -> CommandArgs<'_>

Returns an iterator of the arguments that will be passed to the program.

This does not include the path to the program as the first argument; it only includes the arguments specified with Command::arg and Command::args.

Examples

use std::ffi::OsStr;
use std::process::Command;

let mut cmd = Command::new("echo");
cmd.arg("first").arg("second");
let args: Vec<&OsStr> = cmd.get_args().collect();
assert_eq!(args, &["first", "second"]);
fn get_envs(self: &Self) -> CommandEnvs<'_>

Returns an iterator of the environment variables explicitly set for the child process.

Environment variables explicitly set using Command::env, Command::envs, and Command::env_remove can be retrieved with this method.

Note that this output does not include environment variables inherited from the parent process.

Each element is a tuple key/value pair (&OsStr, Option<&OsStr>). A None value indicates its key was explicitly removed via Command::env_remove. The associated key for the None value will no longer inherit from its parent process.

An empty iterator can indicate that no explicit mappings were added or that Command::env_clear was called. After calling Command::env_clear, the child process will not inherit any environment variables from its parent process.

Examples

use std::ffi::OsStr;
use std::process::Command;

let mut cmd = Command::new("ls");
cmd.env("TERM", "dumb").env_remove("TZ");
let envs: Vec<(&OsStr, Option<&OsStr>)> = cmd.get_envs().collect();
assert_eq!(envs, &[
    (OsStr::new("TERM"), Some(OsStr::new("dumb"))),
    (OsStr::new("TZ"), None)
]);
fn get_current_dir(self: &Self) -> Option<&Path>

Returns the working directory for the child process.

This returns None if the working directory will not be changed.

Examples

use std::path::Path;
use std::process::Command;

let mut cmd = Command::new("ls");
assert_eq!(cmd.get_current_dir(), None);
cmd.current_dir("/bin");
assert_eq!(cmd.get_current_dir(), Some(Path::new("/bin")));
fn get_env_clear(self: &Self) -> bool

Returns whether the environment will be cleared for the child process.

This returns true if Command::env_clear was called, and false otherwise. When true, the child process will not inherit any environment variables from its parent process.

Examples

#![feature(command_resolved_envs)]
use std::process::Command;

let mut cmd = Command::new("ls");
assert_eq!(cmd.get_env_clear(), false);

cmd.env_clear();
assert_eq!(cmd.get_env_clear(), true);

impl CommandExt for process::Command

fn creation_flags(self: &mut Self, flags: u32) -> &mut process::Command
fn show_window(self: &mut Self, cmd_show: u16) -> &mut process::Command
fn force_quotes(self: &mut Self, enabled: bool) -> &mut process::Command
fn raw_arg<S: AsRef<OsStr>>(self: &mut Self, raw_text: S) -> &mut process::Command
fn async_pipes(self: &mut Self, always_async: bool) -> &mut process::Command
fn spawn_with_attributes(self: &mut Self, attribute_list: &ProcThreadAttributeList<'_>) -> io::Result<process::Child>
fn startupinfo_fullscreen(self: &mut Self, enabled: bool) -> &mut process::Command
fn startupinfo_untrusted_source(self: &mut Self, enabled: bool) -> &mut process::Command
fn startupinfo_force_feedback(self: &mut Self, enabled: Option<bool>) -> &mut process::Command
fn inherit_handles(self: &mut Self, inherit_handles: bool) -> &mut process::Command

impl CommandExt for process::Command

fn uid(self: &mut Self, id: u32) -> &mut process::Command
fn gid(self: &mut Self, id: u32) -> &mut process::Command
fn groups(self: &mut Self, groups: &[u32]) -> &mut process::Command
unsafe fn pre_exec<F>(self: &mut Self, f: F) -> &mut process::Command
where
    F: FnMut() -> io::Result<()> + Send + Sync + 'static
fn exec(self: &mut Self) -> io::Error
fn arg0<S>(self: &mut Self, arg: S) -> &mut process::Command
where
    S: AsRef<OsStr>
fn process_group(self: &mut Self, pgroup: i32) -> &mut process::Command
fn chroot<P: AsRef<Path>>(self: &mut Self, dir: P) -> &mut process::Command
fn setsid(self: &mut Self, setsid: bool) -> &mut process::Command

impl CommandExt for process::Command

fn create_pidfd(self: &mut Self, val: bool) -> &mut process::Command

impl Debug for Command

fn fmt(self: &Self, f: &mut fmt::Formatter<'_>) -> fmt::Result

Format the program and arguments of a Command for display. Any non-utf8 data is lossily converted using the utf8 replacement character.

The default format approximates a shell invocation of the program along with its arguments. It does not include most of the other command properties. The output is not guaranteed to work (e.g. due to lack of shell-escaping or differences in path resolution). On some platforms you can use the alternate syntax to show more fields.

Note that the debug implementation is platform-specific.

impl Freeze for Command

impl RefUnwindSafe for Command

impl Send for Command

impl Sync for Command

impl Unpin for Command

impl UnwindSafe for Command

impl<T> Any for Command

fn type_id(self: &Self) -> TypeId

impl<T> Borrow for Command

fn borrow(self: &Self) -> &T

impl<T> BorrowMut for Command

fn borrow_mut(self: &mut Self) -> &mut T

impl<T> From for Command

fn from(t: T) -> T

Returns the argument unchanged.

impl<T, U> Into for Command

fn into(self: Self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

impl<T, U> TryFrom for Command

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

impl<T, U> TryInto for Command

fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>