从 git 挂钩调用时,stdin read_line 不等待用户输入
stdin read_line does not wait for user input when called from a git hook
我是一个绝对的 Rust 初学者,试图构建一个简单的确认功能(是或否),但我无法让用户输入任何内容,该功能只是不断循环而不等待用户输入:
""
""
""
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);
}
}
我已经围绕 guessing game 示例构建了我的函数,我的程序的其余部分什么也不做,只是读取文件和打印文本。
可能是因为我的程序(git 挂钩)的启动方式?
您是否在 Rust Playground 上测试该功能? 运行 终端中的这个程序似乎运行良好。也就是说,不能保证 stdin 会阻塞,但是您可以更改函数以检查字符串是否为空,只有 return 一旦它是空的't.
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 commit hook 在 non-interactive environment 中 运行,你可以按照那个问题中的建议直接打开 /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()
}
注意这不是平台独立的。具体来说,这不太可能适用于 Windows!
我也继续让 io::Result
在整个程序中传播,只在最外层 shell.
恐慌
我是一个绝对的 Rust 初学者,试图构建一个简单的确认功能(是或否),但我无法让用户输入任何内容,该功能只是不断循环而不等待用户输入:
""
""
""
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);
}
}
我已经围绕 guessing game 示例构建了我的函数,我的程序的其余部分什么也不做,只是读取文件和打印文本。
可能是因为我的程序(git 挂钩)的启动方式?
您是否在 Rust Playground 上测试该功能? 运行 终端中的这个程序似乎运行良好。也就是说,不能保证 stdin 会阻塞,但是您可以更改函数以检查字符串是否为空,只有 return 一旦它是空的't.
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 commit hook 在 non-interactive environment 中 运行,你可以按照那个问题中的建议直接打开 /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()
}
注意这不是平台独立的。具体来说,这不太可能适用于 Windows!
我也继续让 io::Result
在整个程序中传播,只在最外层 shell.