Expand description
A module for working with processes.
This module is mostly concerned with spawning and interacting with child
processes, but it also provides abort and exit for terminating the
current process.
§Spawning a process
The Command struct is used to configure and spawn processes:
use std::process::Command;
let output = Command::new("echo")
.arg("Hello world")
.output()
.expect("Failed to execute command");
assert_eq!(b"Hello world\n", output.stdout.as_slice());Several methods on Command, such as spawn or output, can be used
to spawn a process. In particular, output spawns the child process and
waits until the process terminates, while spawn will return a Child
that represents the spawned child process.
§Handling I/O
The stdout, stdin, and stderr of a child process can be
configured by passing an Stdio to the corresponding method on
Command. Once spawned, they can be accessed from the Child. For
example, piping output from one command into another command can be done
like so:
use std::process::{Command, Stdio};
// stdout must be configured with `Stdio::piped` in order to use
// `echo_child.stdout`
let echo_child = Command::new("echo")
.arg("Oh no, a tpyo!")
.stdout(Stdio::piped())
.spawn()
.expect("Failed to start echo process");
// Note that `echo_child` is moved here, but we won't be needing
// `echo_child` anymore
let echo_out = echo_child.stdout.expect("Failed to open echo stdout");
let mut sed_child = Command::new("sed")
.arg("s/tpyo/typo/")
.stdin(Stdio::from(echo_out))
.stdout(Stdio::piped())
.spawn()
.expect("Failed to start sed process");
let output = sed_child.wait_with_output().expect("Failed to wait on sed");
assert_eq!(b"Oh no, a typo!\n", output.stdout.as_slice());Note that ChildStderr and ChildStdout implement Read and
ChildStdin implements Write:
use std::process::{Command, Stdio};
use std::io::Write;
let mut child = Command::new("/bin/cat")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.expect("failed to execute child");
// If the child process fills its stdout buffer, it may end up
// waiting until the parent reads the stdout, and not be able to
// read stdin in the meantime, causing a deadlock.
// Writing from another thread ensures that stdout is being read
// at the same time, avoiding the problem.
let mut stdin = child.stdin.take().expect("failed to get stdin");
std::thread::spawn(move || {
stdin.write_all(b"test").expect("failed to write to stdin");
});
let output = child
.wait_with_output()
.expect("failed to wait on child");
assert_eq!(b"test", output.stdout.as_slice());§Windows argument splitting
On Unix systems arguments are passed to a new process as an array of strings, but on Windows arguments are passed as a single commandline string and it is up to the child process to parse it into an array. Therefore the parent and child processes must agree on how the commandline string is encoded.
Most programs use the standard C run-time argv, which in practice results
in consistent argument handling. However, some programs have their own way of
parsing the commandline string. In these cases using arg or args may
result in the child process seeing a different array of arguments than the
parent process intended.
Two ways of mitigating this are:
- Validate untrusted input so that only a safe subset is allowed.
- Use
raw_argto build a custom commandline. This bypasses the escaping rules used byargso should be used with due caution.
cmd.exe and .bat files use non-standard argument parsing and are especially
vulnerable to malicious input as they may be used to run arbitrary shell
commands. Untrusted arguments should be restricted as much as possible.
For examples on handling this see raw_arg.
§Batch file special handling
On Windows, Command uses the Windows API function CreateProcessW to
spawn new processes. An undocumented feature of this function is that
when given a .bat file as the application to run, it will automatically
convert that into running cmd.exe /c with the batch file as the next argument.
For historical reasons Rust currently preserves this behavior when using
Command::new, and escapes the arguments according to cmd.exe rules.
Due to the complexity of cmd.exe argument handling, it might not be
possible to safely escape some special characters, and using them will result
in an error being returned at process spawn. The set of unescapeable
special characters might change between releases.
Also note that running batch scripts in this way may be removed in the future and so should not be relied upon.
Structs§
- Child
- Representation of a running or exited child process.
- Child
Stderr - A handle to a child process’s stderr.
- Child
Stdin - A handle to a child process’s standard input (stdin).
- Child
Stdout - A handle to a child process’s standard output (stdout).
- Command
- A process builder, providing fine-grained control over how a new process should be spawned.
- Command
Args - An iterator over the command arguments.
- Command
Envs - An iterator over the command environment variables.
- Exit
Code - This type represents the status code the current process can return to its parent under normal termination.
- Exit
Status - Describes the result of a process after it has terminated.
- Output
- The output of a finished process.
- Stdio
- Describes what to do with a standard I/O stream for a child process when
passed to the
stdin,stdout, andstderrmethods ofCommand. - Exit
Status Error Experimental - Describes the result of a process after it has failed
Traits§
- Termination
- A trait for implementing arbitrary return types in the
mainfunction.