rust - 管道输入到标准输入防止 read_line() 阻塞
问题描述
我正在尝试编写一个终端程序,该程序在 CSV 文件中进行管道传输,解析记录,然后根据它们启动测验。我的问题是,一旦我使用 将文件通过管道传输到我的命令行程序中io::stdin()
,我就不能再使用io::stdin().read_line()
它来获取用户输入,因为它会停止阻塞或等待用户输入。以下是最小可重现示例:
use std::io;
fn main() {
let stdin = io::stdin();
println!("Please enter input");
let mut user_input = String::new();
stdin.read_line(&mut user_input).expect("Failed to get input");
println!("The input was {}", user_input);
}
使用cargo run
会导致正常的阻塞行为。使用echo 'Hello World' | cargo run
原因read_line()
不再阻塞整个程序的任何地方。
我认为这不是错误,而是标准输入的工作方式。谁能解释这种行为的细节以及是否有解决方法?
解决方案
我认为这不是错误,而是标准输入的工作方式。
正确的。假设您可以针对 Unix 系统,解决方法是/dev/tty
显式打开:
use std::io::{BufReader, BufRead};
use std::fs::File;
fn main() {
// read piped stuff from stdin...
// read interactive input from the user
let mut input = BufReader::new(File::open("/dev/tty").unwrap());
println!("Please enter input");
let mut user_input = String::new();
input.read_line(&mut user_input).expect("Failed to get input");
println!("The input was {}", user_input);
}
请注意,以这种方式从用户那里获取输入并不是编写命令行程序的惯用方式,因为它不能自动化。相反,考虑支持命令行选项,像clap这样的 crate很方便。
推荐阅读
- puppet - 从 puppet master 向代理共享凭据
- node.js - 如何从 socket.io 仅发送授权域的消息
- c# - 使用 ToAsyncList() 查询数据库后出现 NullReferenceException,但使用 ToList() 时不会出现 NullReferenceException
- html - 当我尝试插入图像时,边框和输入会移动
- java - 设置标签固定大小图像来自数据库
- html - 放大和缩小时按钮的位置发生变化:CSS
- r - 如何将我的一个列的值范围分配给 ggplot2 中的一组颜色?
- python - 使用“Hydrogen”在 Atom 中运行代码时出错
- python-3.x - Pymongo 查询日期失败
- regression - 使用 estout/esttab 为 Stata 中的交互创建回归表