Struct Command
pub struct Command { pub(in ::process) inner: 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!
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("process should execute successfully");
let hello_2 = echo_hello.output().expect("process should execute successfully");
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 should execute successfully");
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 should execute successfully");
Fields
inner: Command
Implementations
impl Command
fn new<S: AsRef<OsStr>>(program: S) -> CommandConstructs a new
Commandfor launching the program at pathprogram, 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
spawnorstatus, but create pipes foroutput
Builder methods are provided to change these defaults and otherwise configure the process.
If
programis not an absolute path, thePATHenvironment variable will be searched in an OS-defined way.Platform-specific behavior
The details below describe the current behavior, but these details may change in future versions of Rust.
On Unix, the
PATHsearched comes from the child's environment:- If the environment is unmodified, the child inherits the parent's
PATHand that is what is searched. - If
PATHis explicitly set viaenv, that new value is searched. - If
env_clearorenv_removeremovesPATHwithout a replacement,execvpfalls back to an OS-defined default (typically/bin:/usr/bin), not the parent'sPATH. This may fail to find programs that rely on the parent'sPATH.
To avoid surprises, use an absolute path or explicitly set
PATHon theCommandwhen modifying the child's environment.On Windows, Rust resolves the executable path before spawning, rather than passing the name to
CreateProcessWfor resolution. Whenprogramis not an absolute path, the following locations are searched in order:- The child's
PATH, if explicitly set viaenv. - The directory of the current executable.
- The system directory (
GetSystemDirectoryW). - The Windows directory (
GetWindowsDirectoryW). - The parent process's
PATH.
Note: when
PATHis cleared viaenv_clearorenv_removeon Windows, step 1 is skipped but the parent process'sPATHis still searched at step 5, unlike on Unix.For executable files, the
.exeextension may be omitted. Files with other extensions must include the extension, otherwise they will not be found. Note that this behavior has some known limitations (see issue #37519).Examples
use std::process::Command; Command::new("sh") .spawn() .expect("sh command should start");Caveats
Command::newis only intended to accept the path of the program. If you pass a program path along with arguments likeCommand::new("ls -l").spawn(), it will try to search forls -lliterally. The arguments need to be passed separately, such as viaargorargs.use std::process::Command; Command::new("ls") .arg("-l") // arg passed separately .spawn() .expect("ls command should start");fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut CommandAdds 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 ascmd.exeand.batfiles use a non-standard way of decoding arguments. They are therefore vulnerable to malicious input.In the case of
cmd.exethis is especially important because a malicious argument can potentially run arbitrary shell commands.See Windows argument splitting for more details or
raw_argfor manually implementing non-standard argument encoding.Examples
use std::process::Command; Command::new("ls") .arg("-l") .arg("-a") .spawn() .expect("ls command should start");fn args<I, S>(&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 ascmd.exeand.batfiles use a non-standard way of decoding arguments. They are therefore vulnerable to malicious input.In the case of
cmd.exethis is especially important because a malicious argument can potentially run arbitrary shell commands.See Windows argument splitting for more details or
raw_argfor manually implementing non-standard argument encoding.Examples
use std::process::Command; Command::new("ls") .args(["-l", "-a"]) .spawn() .expect("ls command should start");fn env<K, V>(&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::envsto set multiple environment variables simultaneously.Child processes will inherit environment variables from their parent process by default. Environment variables explicitly set using
Command::envtake precedence over inherited variables. You can disable environment variable inheritance entirely usingCommand::env_clearor for a single key usingCommand::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 should start");fn envs<I, K, V>(&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::envto set a single environment variable.Child processes will inherit environment variables from their parent process by default. Environment variables explicitly set using
Command::envstake precedence over inherited variables. You can disable environment variable inheritance entirely usingCommand::env_clearor for a single key usingCommand::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 command should start");fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut CommandRemoves 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::envorCommand::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 fromCommand::get_envswill beNone.To clear all explicitly set environment variables and disable all environment variable inheritance, you can use
Command::env_clear.Examples
Prevent any inherited
GIT_DIRvariable from changing the target of thegitcommand, while allowing all other variables, likeGIT_AUTHOR_NAME.use std::process::Command; Command::new("git") .arg("commit") .env_remove("GIT_DIR") .spawn()?; # std::io::Result::Ok(())fn env_clear(&mut self) -> &mut CommandClears 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::envorCommand::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 fromCommand::get_envswill be empty.You can use
Command::env_removeto clear a single mapping.Examples
The behavior of
sortis affected byLANGandLC_*environment variables. Clearing the environment makessort'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>>(&mut self, dir: P) -> &mut CommandSets 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 tocurrent_dir. The behavior in this case is platform specific and unstable, and it's recommended to usecanonicalizeto get an absolute program path instead.Examples
use std::process::Command; Command::new("ls") .current_dir("/bin") .spawn() .expect("ls command should start");fn stdin<T: Into<Stdio>>(&mut self, cfg: T) -> &mut CommandConfiguration for the child process's standard input (stdin) handle.
Defaults to
inheritwhen used withspawnorstatus, and defaults topipedwhen used withoutput.Examples
use std::process::{Command, Stdio}; Command::new("ls") .stdin(Stdio::null()) .spawn() .expect("ls command should start");fn stdout<T: Into<Stdio>>(&mut self, cfg: T) -> &mut CommandConfiguration for the child process's standard output (stdout) handle.
Defaults to
inheritwhen used withspawnorstatus, and defaults topipedwhen used withoutput.Examples
use std::process::{Command, Stdio}; Command::new("ls") .stdout(Stdio::null()) .spawn() .expect("ls command should start");fn stderr<T: Into<Stdio>>(&mut self, cfg: T) -> &mut CommandConfiguration for the child process's standard error (stderr) handle.
Defaults to
inheritwhen used withspawnorstatus, and defaults topipedwhen used withoutput.Examples
use std::process::{Command, Stdio}; Command::new("ls") .stderr(Stdio::null()) .spawn() .expect("ls command should start");fn spawn(&mut self) -> 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.
Errors
This method returns an
io::Errorif the child process could not be spawned. Common reasons include:- the program could not be found (for example, it does not exist, or,
when given a bare name, it is not present in the
PATH); - the current process does not have permission to execute the program
(for example, the file is not marked executable, or execution is
denied by a security policy such as
seccomp); - the operating system could not create the new process because of resource exhaustion (for example, a limit on the number of processes was reached).
An error is only returned for failures that occur while the child is being spawned. Once the child has started successfully, anything that happens to it afterwards — including being terminated by a signal — is reported through its
ExitStatusrather than as an error from the spawning method.Examples
use std::process::Command; Command::new("ls") .spawn() .expect("ls command should start");- the program could not be found (for example, it does not exist, or,
when given a bare name, it is not present in the
fn output(&mut self) -> 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.
Errors
Like
spawn, this method returns anio::Errorif the child process could not be spawned; seespawnfor the common reasons. It may also return an error if reading the child's output or waiting on the child fails.Note that this method does not return an error if the child runs and then exits unsuccessfully, or is terminated by a signal. In those cases it still returns
Ok, and the outcome is reflected in theExitStatusstored in the returnedOutput.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(&mut self) -> 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.
Errors
Like
spawn, this method returns anio::Errorif the child process could not be spawned; seespawnfor the common reasons. It may also return an error if waiting on the child fails.Note that this method does not return an error if the child runs and then exits unsuccessfully, or is terminated by a signal. In those cases it still returns
Ok, and the outcome is reflected in the returnedExitStatus.Examples
use std::process::Command; let status = Command::new("/bin/cat") .arg("file.txt") .status() .expect("process should execute successfully"); println!("process finished with: {status}"); assert!(status.success());fn get_program(&self) -> &OsStrReturns the path to the program that was given to
Command::new.Examples
use Command; let cmd = new; assert_eq!;fn get_args(&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::argandCommand::args.Examples
use OsStr; use Command; let mut cmd = new; cmd.arg.arg; let args: = cmd.get_args.collect; assert_eq!;fn get_envs(&self) -> CommandEnvs<'_>Returns an iterator of the environment variables explicitly set for the child process.
Environment variables explicitly set using
Command::env,Command::envs, andCommand::env_removecan be retrieved with this method.Note that this output does not include environment variables inherited from the parent process. To see the full list of environment variables, including those inherited from the parent process, use
Command::get_resolved_envs.Each element is a tuple key/value pair
(&OsStr, Option<&OsStr>). ANonevalue indicates its key was explicitly removed viaCommand::env_remove. The associated key for theNonevalue will no longer inherit from its parent process.An empty iterator can indicate that no explicit mappings were added or that
Command::env_clearwas called. After callingCommand::env_clear, the child process will not inherit any environment variables from its parent process.Examples
use OsStr; use Command; let mut cmd = new; cmd.env.env_remove; let envs: = cmd.get_envs.collect; assert_eq!;fn get_resolved_envs(&self) -> CommandResolvedEnvsReturns an iterator of the environment variables that will be set when the process is spawned.
This returns the environment as it would be if the command were executed at the time of calling this method. The returned environment includes:
- All inherited environment variables from the parent process (unless
Command::env_clearwas called) - All environment variables explicitly set via
Command::envorCommand::envs - Excluding any environment variables removed via
Command::env_remove
Note that the returned environment is a snapshot at the time this method is called and will not reflect any subsequent changes to the
Commandor the parent process's environment. Additionally, it will not reflect changes made in apre_exechook (on Unix platforms).Each element is a tuple
(OsString, OsString)representing an environment variable key and value.Examples
use Command; use ; use env; use HashMap; let mut cmd = new; cmd.env; unsafe let resolved: = cmd.get_resolved_envs.collect; assert_eq!; assert_eq!;- All inherited environment variables from the parent process (unless
fn get_current_dir(&self) -> Option<&Path>Returns the working directory for the child process.
This returns
Noneif the working directory will not be changed.Examples
use Path; use Command; let mut cmd = new; assert_eq!; cmd.current_dir; assert_eq!;fn get_env_clear(&self) -> boolReturns whether the environment will be cleared for the child process.
This returns
trueifCommand::env_clearwas called, andfalseotherwise. Whentrue, the child process will not inherit any environment variables from its parent process.Examples
use Command; let mut cmd = new; assert_eq!; cmd.env_clear; assert_eq!;
Trait Implementations
impl AsInner<Command> for Command
fn as_inner(&self) -> &Command
impl AsInnerMut<Command> for Command
fn as_inner_mut(&mut self) -> &mut Command
impl CommandExt for Command
fn uid(&mut self, id: u32) -> &mut Commandfn gid(&mut self, id: u32) -> &mut Commandfn groups(&mut self, groups: &[u32]) -> &mut Commandunsafe fn pre_exec<F>(&mut self, f: F) -> &mut Command where F: FnMut() -> Result<()> + Send + Sync + 'static,fn exec(&mut self) -> Errorfn arg0<S>(&mut self, arg: S) -> &mut Command where S: AsRef<OsStr>,fn process_group(&mut self, pgroup: i32) -> &mut Commandfn chroot<P: AsRef<Path>>(&mut self, dir: P) -> &mut Commandfn setsid(&mut self, setsid: bool) -> &mut Command
impl CommandExt for Command
fn create_pidfd(&mut self, val: bool) -> &mut Command
impl CommandExt for Command
fn creation_flags(&mut self, flags: u32) -> &mut Commandfn desktop<S: AsRef<OsStr>>(&mut self, desktop: S) -> &mut Commandfn show_window(&mut self, cmd_show: u16) -> &mut Commandfn force_quotes(&mut self, enabled: bool) -> &mut Commandfn raw_arg<S: AsRef<OsStr>>(&mut self, raw_text: S) -> &mut Commandfn async_pipes(&mut self, always_async: bool) -> &mut Commandfn spawn_with_attributes(&mut self, attribute_list: &ProcThreadAttributeList<'_>) -> Result<Child>fn startupinfo_fullscreen(&mut self, enabled: bool) -> &mut Commandfn startupinfo_untrusted_source(&mut self, enabled: bool) -> &mut Commandfn startupinfo_force_feedback(&mut self, enabled: Option<bool>) -> &mut Commandfn inherit_handles(&mut self, inherit_handles: bool) -> &mut Command
impl Debug for Command
fn fmt(&self, f: &mut Formatter<'_>) -> ResultFormat 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.
Auto Trait Implementations
impl !RefUnwindSafe for Command
impl !UnwindSafe for Command
impl Freeze for Command
impl Send for Command
impl Sync for Command
impl Unpin for Command
impl UnsafeUnpin for Command
Blanket Implementations
impl<T> Any for Command
where
T: 'static + ?Sized,
fn type_id(&self) -> TypeId
impl<T> Borrow<T> for Command
where
T: ?Sized,
fn borrow(&self) -> &T
impl<T> BorrowMut<T> for Command
where
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
impl<T> From<T> for Command
fn from(t: T) -> TReturns the argument unchanged.
impl<T> SizeHint for Command
where
T: ?Sized,
fn lower_bound(&self) -> usizefn upper_bound(&self) -> Option<usize>
impl<T> SizedTypeProperties for Command
impl<T, U> Into<U> for Command
where
U: From<T>,
fn into(self) -> UCalls
U::from(self).That is, this conversion is whatever the implementation of
[From]<T> for Uchooses to do.
impl<T, U> TryFrom<U> for Command
where
U: Into<T>,
type Error = Infallible;fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
impl<T, U> TryInto<U> for Command
where
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error;fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>