pub struct Pipeline { /* private fields */ }Expand description
A builder for pipelines of subprocesses connected via pipes.
A pipeline is a sequence of two or more Exec commands connected via pipes. Just
like in a Unix shell pipeline, each command receives standard input from the previous
command, and passes standard output to the next command. Optionally, the standard
input of the first command can be provided from the outside, and the output of the
last command can be captured.
In most cases you do not need to create Pipeline instances directly; instead,
combine Exec instances using the | operator which produces Pipeline.
§Examples
Execute a pipeline and return the exit status of the last command:
let exit_status =
(Exec::shell("ls *.bak") | Exec::cmd("xargs").arg("rm")).join()?;Capture the pipeline’s output:
let dir_checksum = {
Exec::shell("find . -type f") | Exec::cmd("sort") | Exec::cmd("sha1sum")
}.capture()?.stdout_str();Implementations§
Source§impl Pipeline
impl Pipeline
Sourcepub fn new() -> Pipeline
pub fn new() -> Pipeline
Creates a new empty pipeline.
Use pipe to add commands to the pipeline, or the | operator
to combine Exec instances.
An empty pipeline’s join() returns success and capture() returns empty
output. A single-command pipeline behaves like the command run on its own.
Sourcepub fn pipe(self, cmd: Exec) -> Pipeline
pub fn pipe(self, cmd: Exec) -> Pipeline
Appends a command to the pipeline.
This is the builder-style equivalent of the | operator.
§Example
let output = Pipeline::new()
.pipe(Exec::cmd("echo").arg("hello world"))
.pipe(Exec::cmd("wc").arg("-w"))
.capture()?
.stdout_str();Sourcepub fn stdin<T>(self, stdin: T) -> Pipelinewhere
InputRedirection: FromSource<T>,
pub fn stdin<T>(self, stdin: T) -> Pipelinewhere
InputRedirection: FromSource<T>,
Specifies the source for the standard input of the first command in the pipeline.
The source can be:
- a
Redirection; - a
File, which is a shorthand forRedirection::File(file); - a
Vec<u8>,&str,&[u8],Box<[u8]>, or[u8; N], which will set up aRedirection::Pipefor stdin, feeding that data into the standard input of the subprocess; - an
InputData, which also sets up a pipe, but wraps any reader and feeds its content to the standard input of the subprocess. UseInputData::from_bytesfor in-memory byte containers not covered by the above, likebytes::Bytesormemmap2::Mmap. UseInputData::from_readerfor a customReadthat generates or transforms data.
If the child exits before consuming all input, the BrokenPipe error is silently
ignored. Use the exit status and output to check if the child processed the input
correctly.
Sourcepub fn stdout<T>(self, stdout: T) -> Pipelinewhere
Redirection: FromSink<T>,
pub fn stdout<T>(self, stdout: T) -> Pipelinewhere
Redirection: FromSink<T>,
Specifies the sink for the standard output of the last command in the pipeline.
The sink can be:
- a
Redirection; - a
File, which is a shorthand forRedirection::File(file).
Sourcepub fn stderr_all<T>(self, stderr: T) -> Pipelinewhere
Redirection: FromSink<T>,
pub fn stderr_all<T>(self, stderr: T) -> Pipelinewhere
Redirection: FromSink<T>,
Specifies the sink for the standard error of all commands in the pipeline.
Unlike stdout(), which only affects the last command in the pipeline, this
affects all commands. The difference is because standard output is piped from one
command to the next, so only the output of the last command is “free”. In
contrast, the standard errors are not connected to each other and can be
configured en masse.
The sink can be:
- a
Redirection; - a
File, which is a shorthand forRedirection::File(file).
All Redirection variants are meaningful:
Redirection::None- inherit from the parent (the default)Redirection::Pipe- funnel stderr of all commands into stderr obtained withcapture()orcommunicate()Redirection::Merge- redirect stderr to stdout, like2>&1for each commandRedirection::File(f)- redirect to a fileRedirection::Null- suppress stderr
Note that this differs from the shell’s cmd1 | cmd2 2>file, which only
redirects stderr of the last command. This method is equivalent to (cmd1 | cmd2) 2>file, but without the overhead of a subshell.
If you pass Redirection::Pipe, the shared stderr read end
will be available via Job::stderr.
Sourcepub fn cwd(self, dir: impl AsRef<Path>) -> Pipeline
pub fn cwd(self, dir: impl AsRef<Path>) -> Pipeline
Specifies the current working directory for all commands in the pipeline.
If unspecified, the current working directory is inherited from the parent.
Sourcepub fn detached(self) -> Pipeline
pub fn detached(self) -> Pipeline
Specifies that the pipeline processes are initially detached.
A detached pipeline means that we will not wait for the processes to finish when the objects that own them go out of scope.
Sourcepub fn start(self) -> Result<Job>
pub fn start(self) -> Result<Job>
Starts all commands in the pipeline and returns a Job with the running
processes and their pipe ends.
If some command fails to start, the remaining commands will not be started, and
the appropriate error will be returned. The commands that have already started
will be waited to finish (but will probably exit immediately due to missing
output), except for the ones for which detached() was called. This is
equivalent to what the shell does.
Sourcepub fn join(self) -> Result<ExitStatus>
pub fn join(self) -> Result<ExitStatus>
Starts the pipeline, waits for it to finish, and returns the exit status of the last command.
Sourcepub fn stream_stdout(self) -> Result<impl Read>
pub fn stream_stdout(self) -> Result<impl Read>
Starts the pipeline and returns a value implementing the Read trait that reads
from the standard output of the last command.
This will automatically set up stdout(Redirection::Pipe), so it is not necessary
to do that beforehand.
When the trait object is dropped, it will wait for the pipeline to finish. If
this is undesirable, use detached().
§Panics
Panics if input data was specified with stdin. Use
capture or communicate to both
feed input and read output.
Sourcepub fn stream_stderr_all(self) -> Result<impl Read>
pub fn stream_stderr_all(self) -> Result<impl Read>
Starts the pipeline and returns a value implementing the Read trait that reads
from the standard error of all commands in the pipeline.
This will automatically set up stderr_all(Redirection::Pipe), so it is not
necessary to do that beforehand.
Note that this redirects stderr of all commands in the pipeline, not just
the last one. This differs from the shell’s cmd1 | cmd2 2>file, which
only redirects stderr of the last command. This method is equivalent to
(cmd1 | cmd2) 2>file, but without the overhead of a subshell.
When the trait object is dropped, it will wait for the pipeline to finish. If
this is undesirable, use detached().
§Panics
Panics if input data was specified with stdin. Use
capture or communicate to both
feed input and read output.
Sourcepub fn stream_stdin(self) -> Result<impl Write>
pub fn stream_stdin(self) -> Result<impl Write>
Starts the pipeline and returns a value implementing the Write trait that writes
to the standard input of the first command.
This will automatically set up stdin(Redirection::Pipe), so it is not necessary
to do that beforehand.
When the trait object is dropped, it will wait for the pipeline to finish. If this
is undesirable, use detached().
§Panics
Panics if input data was specified with stdin.
Sourcepub fn communicate(self) -> Result<Communicator>
pub fn communicate(self) -> Result<Communicator>
Starts the pipeline and returns a Communicator handle.
Unless already configured, stdout and stderr are redirected to pipes. If you
need different redirection (e.g. stderr_all(Merge)), set it up before
calling this method and it will be preserved.
Compared to capture(), this offers more choice in how communication is
performed, such as read size limit and timeout. Unlike capture(), this
method doesn’t wait for the pipeline to finish, effectively detaching it.
Sourcepub fn capture(self) -> Result<Capture>
pub fn capture(self) -> Result<Capture>
Starts the pipeline, collects its output, and waits for it to finish.
The return value provides the standard output and standard error as bytes or optionally strings, as well as the exit status.
Unless already configured, stdout and stderr are redirected to pipes so they
can be captured. If you need different redirection (e.g. stderr_all(Merge)),
set it up before calling this method and it will be preserved.
This method waits for the pipeline to finish, rather than simply waiting for
its standard streams to close. If this is undesirable, use detached().
Trait Implementations§
Source§impl FromIterator<Exec> for Pipeline
impl FromIterator<Exec> for Pipeline
Source§fn from_iter<I: IntoIterator<Item = Exec>>(iter: I) -> Self
fn from_iter<I: IntoIterator<Item = Exec>>(iter: I) -> Self
Creates a pipeline from an iterator of commands.
The iterator may yield any number of commands, including zero or one.
An empty pipeline returns success on join() and empty output on
capture(). A single-command pipeline behaves like running that
command directly.
§Example
use subprocess::{Exec, Pipeline};
let commands = vec![
Exec::shell("echo tset"),
Exec::shell("tr '[:lower:]' '[:upper:]'"),
Exec::shell("rev")
];
let pipeline: Pipeline = commands.into_iter().collect();
let output = pipeline.capture().unwrap().stdout_str();
assert_eq!(output, "TEST\n");