Struct Stdio

struct Stdio(_)

Describes what to do with a standard I/O stream for a child process when passed to the stdin, stdout, and stderr methods of Command.

Implementations

impl Stdio

fn piped() -> Stdio

A new pipe should be arranged to connect the parent and child processes.

Examples

With stdout:

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

let output = Command::new("echo")
    .arg("Hello, world!")
    .stdout(Stdio::piped())
    .output()
    .expect("Failed to execute command");

assert_eq!(String::from_utf8_lossy(&output.stdout), "Hello, world!\n");
// Nothing echoed to console

With stdin:

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

let mut child = Command::new("rev")
    .stdin(Stdio::piped())
    .stdout(Stdio::piped())
    .spawn()
    .expect("Failed to spawn child process");

let mut stdin = child.stdin.take().expect("Failed to open stdin");
std::thread::spawn(move || {
    stdin.write_all("Hello, world!".as_bytes()).expect("Failed to write to stdin");
});

let output = child.wait_with_output().expect("Failed to read stdout");
assert_eq!(String::from_utf8_lossy(&output.stdout), "!dlrow ,olleH");

Writing more than a pipe buffer's worth of input to stdin without also reading stdout and stderr at the same time may cause a deadlock. This is an issue when running any program that doesn't guarantee that it reads its entire stdin before writing more than a pipe buffer's worth of output. The size of a pipe buffer varies on different targets.

fn inherit() -> Stdio

The child inherits from the corresponding parent descriptor.

Examples

With stdout:

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

let output = Command::new("echo")
    .arg("Hello, world!")
    .stdout(Stdio::inherit())
    .output()
    .expect("Failed to execute command");

assert_eq!(String::from_utf8_lossy(&output.stdout), "");
// "Hello, world!" echoed to console

With stdin:

use std::process::{Command, Stdio};
use std::io::{self, Write};

let output = Command::new("rev")
    .stdin(Stdio::inherit())
    .stdout(Stdio::piped())
    .output()?;

print!("You piped in the reverse of: ");
io::stdout().write_all(&output.stdout)?;
# io::Result::Ok(())
fn null() -> Stdio

This stream will be ignored. This is the equivalent of attaching the stream to /dev/null.

Examples

With stdout:

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

let output = Command::new("echo")
    .arg("Hello, world!")
    .stdout(Stdio::null())
    .output()
    .expect("Failed to execute command");

assert_eq!(String::from_utf8_lossy(&output.stdout), "");
// Nothing echoed to console

With stdin:

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

let output = Command::new("rev")
    .stdin(Stdio::null())
    .stdout(Stdio::piped())
    .output()
    .expect("Failed to execute command");

assert_eq!(String::from_utf8_lossy(&output.stdout), "");
// Ignores any piped-in input
fn makes_pipe(self: &Self) -> bool

Returns true if this requires Command to create a new pipe.

Example

#![feature(stdio_makes_pipe)]
use std::process::Stdio;

let io = Stdio::piped();
assert_eq!(io.makes_pipe(), true);

impl Debug for Stdio

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

impl Freeze for Stdio

impl From for Stdio

fn from(file: fs::File) -> Stdio

Converts a File into a Stdio.

Examples

File will be converted to Stdio using Stdio::from under the hood.

use std::fs::File;
use std::process::Command;

// With the `foo.txt` file containing "Hello, world!"
let file = File::open("foo.txt")?;

let reverse = Command::new("rev")
    .stdin(file)  // Implicit File conversion into a Stdio
    .output()?;

assert_eq!(reverse.stdout, b"!dlrow ,olleH");
# std::io::Result::Ok(())

impl From for Stdio

fn from(inherit: io::Stderr) -> Stdio

Redirect command stdout/stderr to our stderr

Examples

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

# fn test() -> Result<(), Box<dyn std::error::Error>> {
let output = Command::new("whoami")
    .stdout(io::stderr())
    .output()?;
output.status.exit_ok()?;
assert!(output.stdout.is_empty());
# Ok(())
# }
#
# if cfg!(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos"))))) {
#     test().unwrap();
# }

impl From for Stdio

fn from(child: ChildStdout) -> Stdio

Converts a ChildStdout into a Stdio.

Examples

ChildStdout will be converted to Stdio using Stdio::from under the hood.

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

let hello = Command::new("echo")
    .arg("Hello, world!")
    .stdout(Stdio::piped())
    .spawn()
    .expect("failed echo command");

let reverse = Command::new("rev")
    .stdin(hello.stdout.unwrap())  // Converted into a Stdio here
    .output()
    .expect("failed reverse command");

assert_eq!(reverse.stdout, b"!dlrow ,olleH\n");

impl From for Stdio

fn from(pipe: io::PipeReader) -> Self

impl From for Stdio

fn from(child: ChildStderr) -> Stdio

Converts a ChildStderr into a Stdio.

Examples

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

let reverse = Command::new("rev")
    .arg("non_existing_file.txt")
    .stderr(Stdio::piped())
    .spawn()
    .expect("failed reverse command");

let cat = Command::new("cat")
    .arg("-")
    .stdin(reverse.stderr.unwrap()) // Converted into a Stdio here
    .output()
    .expect("failed echo command");

assert_eq!(
    String::from_utf8_lossy(&cat.stdout),
    "rev: cannot open non_existing_file.txt: No such file or directory\n"
);

impl From for Stdio

fn from(inherit: io::Stdout) -> Stdio

Redirect command stdout/stderr to our stdout

Examples

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

# fn test() -> Result<(), Box<dyn std::error::Error>> {
let output = Command::new("whoami")
    .stdout(io::stdout())
    .output()?;
output.status.exit_ok()?;
assert!(output.stdout.is_empty());
# Ok(())
# }
#
# if cfg!(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos"))))) {
#     test().unwrap();
# }

impl From for Stdio

fn from(pipe: io::PipeWriter) -> Self

impl From for Stdio

fn from(child: ChildStdin) -> Stdio

Converts a ChildStdin into a Stdio.

Examples

ChildStdin will be converted to Stdio using Stdio::from under the hood.

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

let reverse = Command::new("rev")
    .stdin(Stdio::piped())
    .spawn()
    .expect("failed reverse command");

let _echo = Command::new("echo")
    .arg("Hello, world!")
    .stdout(reverse.stdin.unwrap()) // Converted into a Stdio here
    .output()
    .expect("failed echo command");

// "!dlrow ,olleH" echoed to console

impl From for process::Stdio

fn from(fd: OwnedFd) -> process::Stdio

Takes ownership of a file descriptor and returns a Stdio that can attach a stream to it.

impl From for process::Stdio

fn from(handle: OwnedHandle) -> process::Stdio

Takes ownership of a handle and returns a Stdio that can attach a stream to it.

impl FromRawFd for process::Stdio

unsafe fn from_raw_fd(fd: RawFd) -> process::Stdio

impl FromRawHandle for process::Stdio

unsafe fn from_raw_handle(handle: RawHandle) -> process::Stdio

impl RefUnwindSafe for Stdio

impl Send for Stdio

impl Sync for Stdio

impl Unpin for Stdio

impl UnwindSafe for Stdio

impl<T> Any for Stdio

fn type_id(self: &Self) -> TypeId

impl<T> Borrow for Stdio

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

impl<T> BorrowMut for Stdio

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

impl<T> From for Stdio

fn from(t: T) -> T

Returns the argument unchanged.

impl<T, U> Into for Stdio

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 Stdio

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

impl<T, U> TryInto for Stdio

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