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());
RunSeveral 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());
RunNote 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());
RunStructs
Traits
main
function.