Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling piped data stdin with Rust

Tags:

stdin

rust

I'm having trouble with stdin in Rust. I'm trying to process stdin comming from a pipe on a linux terminal, something like grep for example.

echo "lorem ipsum" | grep <text>

Im using this in rust:

fn load_stdin() -> Result<String> {
    let mut buffer = String::new();
    let stdin = stdin();
    stdin.read_line(&mut buffer)?;
    return Ok(buffer);
}

But the problem is that if I don't bring in any piped data I get prompted to write, I would instead like to return Err.

So basically, if I do something like:

ls | cargo run
user@machine: ~ $ 

All is good. But if I do not pipe any stdin:

cargo run

The program halts and waits for user input.

like image 617
DigitalCyan Avatar asked Sep 14 '25 09:09

DigitalCyan


1 Answers

You can use the atty crate to test whether your standard input is redirected:

use std::io;

use atty::Stream;

fn load_stdin() -> io::Result<String> {
    if atty::is(Stream::Stdin) {
        return Err(io::Error::new(io::ErrorKind::Other, "stdin not redirected"));
    }
    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer)?;
    return Ok(buffer);
}

fn main() -> io::Result<()> {
    println!("line: {}", load_stdin()?);
    Ok(())
}

This results in the desired behavior:

$ echo "lorem ipsum" | cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/playground`
line: lorem ipsum
$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/playground`
Error: Custom { kind: Other, error: "stdin not redirected" }
like image 121
user4815162342 Avatar answered Sep 17 '25 01:09

user4815162342