Rust 当从git钩子调用stdin read_行时,它不会等待用户输入

Rust 当从git钩子调用stdin read_行时,它不会等待用户输入,rust,githooks,tty,Rust,Githooks,Tty,我是一个尝试构建简单确认函数(是或否)的绝对新手,但我无法让用户键入任何内容,该函数只是在不等待用户输入的情况下不断循环: "" "" "" etc. 是以下简化版本的结果 use std::process; use std::io; pub fn confirm() { loop { let mut answer = String::new(); io::stdin().read_line(&mut answer) .ok() .e

我是一个尝试构建简单确认函数(是或否)的绝对新手,但我无法让用户键入任何内容,该函数只是在不等待用户输入的情况下不断循环:

""
""
""
etc.  
是以下简化版本的结果

use std::process;
use std::io;

pub fn confirm() {
  loop {
    let mut answer = String::new();

    io::stdin().read_line(&mut answer)
      .ok()
      .expect("Failed to read line");

    println!("{:?}", answer);
  }
}
我已经围绕这个例子构建了我的函数,而我的程序的其余部分什么都不做,只是读取一个文件并打印文本


可能是由于我的程序(git钩子)的启动方式造成的?

您是否在上测试该函数?在终端上运行这个程序似乎很好。也就是说,不能保证stdin会被阻塞,但是您可以更改函数来检查字符串是否为空,并且只在字符串为空时返回

use std::io;

fn main() {
    println!("{:?}", confirm());
}

fn confirm() -> String {
    loop {
        let mut answer = String::new();

        io::stdin().read_line(&mut answer)
                   .ok()
                   .expect("Failed to read line");

        if !answer.is_empty() && answer != "\n" && answer != "\r\n" {
            return answer
        }
    }
}

假设问题是git提交钩子正在运行,您可以按照问题中给出的建议直接打开
/dev/tty
。与STDIN不同,我们不将其视为神奇的全局变量,而是将其传递到我们需要的地方:

use std::io::{self, BufRead, BufReader};
use std::fs::File;

type Tty = BufReader<File>;

fn open_tty() -> io::Result<Tty> {
    let f = try!(File::open("/dev/tty"));
    Ok(BufReader::new(f))
}

fn confirm(tty: &mut Tty) -> io::Result<String> {
    let mut answer = String::new();
    try!(tty.read_line(&mut answer));
    Ok(answer)
}

fn inner_main() -> io::Result<()> {
    let mut tty = try!(open_tty());
    let answer = try!(confirm(&mut tty));

    println!("The answer was: {}", answer);

    Ok(())
}

fn main() {
    inner_main().unwrap()
}
使用std::io:{self,BufRead,BufReader};
使用std::fs::File;
Tty型=BufReader;
fn open_tty()->io::Result{
让f=try!(文件::open(“/dev/tty”);
Ok(BufReader::new(f))
}
fn确认(tty:&mut tty)->io::结果{
让mut answer=String::new();
试一试!(tty.read_line(&mut answer));
好的(回答)
}
fn内部_main()->io::结果{
让mut tty=try!(打开_tty());
让答案=尝试!(确认(&mut tty));
println!(“答案是:{}”,答案);
好(())
}
fn main(){
内部_main().展开()
}
注意这不是独立于平台的。具体来说,这不太可能在Windows上工作


我还允许
io::Result
在整个程序中传播,只是在最外层的外壳上惊慌失措。

你也可能应该在循环中
thread::sleep(…)
一点,否则如果读取行没有阻塞,这可能会很忙。就像我说的,在windows和OSX上,我从来没有让它不阻塞过。从文档中也可以看出,它并没有说如果不阻塞一次,下一次就不会阻塞。这很公平,但它无法保证它会阻塞。在这种情况下,程序将在循环中旋转,直到有人杀死它。什么样的钩子?例如,似乎有一些技巧。