What's the best way to ask for a password?
⚓ Rust 📅 2026-03-04 👤 surdeus 👁️ 3I always wondered how to hide stdin, and now I came across a solution: stty -echo. This just stops keystrokes from being printed. Very simple! Naturally, I had to try it in Rust:
use std::{
error::Error,
process::Command,
io::{self, BufRead},
};
fn main() -> Result<(), Box<dyn Error>> {
println!("\nEnter password:");
// Hide stdin
assert_eq!(
Command::new("stty")
.arg("-echo")
.spawn()?
.wait()?
.code()
.unwrap(),
0
);
let mut buf = String::new();
io::stdin()
.read_line(&mut buf)
.unwrap();
println!("Your password was `{}`", buf.trim());
// Reset terminal
assert_eq!(
Command::new("stty")
.arg("echo")
.spawn()?
.wait()?
.code()
.unwrap(),
0
);
Ok(())
}
This works as expected, and prints:
Enter password:
// User typed `Hello, world`, but it is hidden
Enter password:
Your password was `Hello, world`.
However, I didn't like the fact that the password is typed on a different line, so I tried to make it so that the (hidden) password is typed directly after the Enter password: prompt, like how sudo does it.
Like so:
use std::{
error::Error,
process::Command,
io::{self, BufRead},
};
fn main() -> Result<(), Box<dyn Error>> {
print!("\nEnter password:");
// Hide stdin
assert_eq!(
Command::new("stty")
.arg("-echo")
.spawn()?
.wait()?
.code()
.unwrap(),
0
);
let mut stdin = io::stdin().lock();
let mut buf = Vec::new();
stdin.read_until(b"\n"[0], &mut buf)?;
println!("Your password was `{}`", String::from_utf8(buf)?.trim());
// Reset terminal
assert_eq!(
Command::new("stty")
.arg("echo")
.spawn()?
.wait()?
.code()
.unwrap(),
0
);
Ok(())
}
This should read stdin after the prompt, and stopping when a newline is reached.
However, it produces this strange output:
// No prompt, but stdin is being consumed. User types `Hello, world` and it is hidden
Enter password:Your password was `Hello, world`
I imagine this is a somewhat unavoidable issue caused by stty hiding the whole line or something.
Is there any way to achieve this?
Any help is appreciated. Thanks!
5 posts - 5 participants
🏷️ Rust_feed