You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Rust程序读取通过管道传入的进程输出?

如何在Rust中逐行实时读取管道输入

没问题!在Rust里处理通过管道传入的命令输出其实非常直观,核心就是读取标准输入(stdin)——因为管道机制本质是把前一个程序的标准输出(stdout)直接作为你的程序的标准输入。下面我给你一步步讲怎么实现:

核心实现代码

我们可以用标准库的std::io::BufReader来高效逐行读取输入,它能流式处理数据,保证实时性(不用等所有输入都传完才开始处理):

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

fn main() {
    // 获取标准输入的锁定BufReader,确保读取效率和线程安全
    let stdin = io::stdin();
    let reader = stdin.lock();

    // 逐行迭代输入内容
    for line_result in reader.lines() {
        match line_result {
            // 成功读取一行,直接打印
            Ok(line) => println!("{}", line),
            // 读取出错时输出错误信息
            Err(error) => eprintln!("读取输入失败: {}", error),
        }
    }
}

测试验证

现在你可以测试不同的管道场景:

  • 执行 pwd | cargo run:程序会实时打印当前目录路径
  • 执行 find . | cargo run:程序会逐行输出find命令找到的所有文件/目录,完全是实时流式输出,不会等find执行完才显示结果

扩展:判断是否有管道输入

如果想在用户直接运行cargo run(没有管道输入)时给出提示,可以用atty crate来判断stdin是否来自终端:

  1. 先在Cargo.toml里添加依赖:
[dependencies]
atty = "0.2"
  1. 修改代码:
use std::io::{self, BufRead};
use atty::Stream;

fn main() {
    // 判断标准输入是否来自终端(即没有管道输入)
    if atty::is(Stream::Stdin) {
        eprintln!("请通过管道传入数据,例如:pwd | cargo run");
        std::process::exit(1);
    }

    let stdin = io::stdin();
    for line_result in stdin.lock().lines() {
        match line_result {
            Ok(line) => println!("{}", line),
            Err(error) => eprintln!("读取输入失败: {}", error),
        }
    }
}

这样用户直接运行程序时会收到提示,避免程序一直等待输入的困惑。

内容的提问来源于stack exchange,提问作者AbhiNickz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:16:07