Reputation: 80
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.
Upvotes: 3
Views: 2301
Reputation: 154866
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" }
Upvotes: 6