console-rs / dialoguer

Rust utility library for nice command line prompts and similar things
MIT License
1.33k stars 142 forks source link

`Password`: Returns `Err` when used in conjunction with input via redirect or pipe #296

Open sorairolake opened 11 months ago

sorairolake commented 11 months ago

The following code reads bytes from stdin and then enters the password:

use std::io::{self, Read};

use dialoguer::{theme::ColorfulTheme, Password};

fn main() {
    let mut buf = Vec::new();
    io::stdin().read_to_end(&mut buf).unwrap();

    let passphrase = Password::with_theme(&ColorfulTheme::default())
        .with_prompt("Enter passphrase")
        .with_confirmation("Confirm passphrase", "Passphrases mismatch, try again")
        .interact()
        .unwrap();

    println!("{buf:?}");
    println!("{passphrase}");
}

This works well when the user enters bytes directly. However, when inputting bytes via redirect or pipe (e.g. echo "foo" | cmd or cmd < infile), this returns Bad file descriptor when entering the password.

called `Result::unwrap()` on an `Err` value: IO(Os { code: 9, kind: Uncategorized, message: "Bad file descriptor" })
hepptho commented 10 months ago

Not sure if it's related, but I have a similar problem with FuzzySelect.

Example:

use dialoguer::FuzzySelect;

fn main() {
    let options = ["abc", "def", "ghi"];
    let index = FuzzySelect::new()
        .with_prompt("Select")
        .items(&options)
        .interact().unwrap();
    println!("selected: {}", options[index]);
}

This works fine when stdin is empty, but when piping anything into the command it will crash:

thread 'main' panicked at src\main.rs:8:21:
called `Result::unwrap()` on an `Err` value: IO(Os { code: 1, kind: Uncategorized, message: "Incorrect function." })

I am on windows, msvc toolchain, rust 1.75.0.

mike-lloyd03 commented 9 months ago

I'm having the same issue running on Linux. Piping from another process raises an error IO error: Bad file descriptor (os error 9).

Anyone figured out a workaround?