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

如何让Rust调用Shell脚本时传递read提示并等待用户输入?

在Rust中调用带交互式输入的Shell脚本并处理用户交互

你的问题在于当前代码仅启动了子进程,但未处理子进程的输入输出流——脚本的read提示被存放在管道中未输出到终端,用户输入也无法传递给子进程。以下是两种解决办法:

方法1:让子进程直接继承终端(最简单方案)

如果不需要捕获脚本输出,直接让子进程复用当前进程的标准输入、输出、错误流即可,脚本的交互会直接与终端对接:

use std::process::Command;

fn main() {
    // status()会等待子进程执行完成,默认继承父进程的IO流
    let exit_status = Command::new("/bin/bash")
        .arg("./myscript.sh")
        .status()
        .expect("启动脚本失败");

    println!("脚本退出状态: {}", exit_status);
}

运行后,脚本的read -p提示会直接显示在终端,输入内容后脚本会继续执行并输出结果。

方法2:手动处理输入输出流(需捕获输出时使用)

如果需要捕获脚本输出同时处理交互,需手动读写子进程的管道:

use std::io::{self, BufRead, BufReader, Write};
use std::process::{Command, Stdio};

fn main() {
    let mut child = Command::new("/bin/bash")
        .arg("./myscript.sh")
        .stdout(Stdio::piped())
        .stdin(Stdio::piped())
        .stderr(Stdio::inherit()) // 让错误信息直接输出到终端
        .spawn()
        .expect("启动脚本失败");

    // 读取子进程的stdout,显示read的提示信息
    let stdout = child.stdout.take().unwrap();
    let mut reader = BufReader::new(stdout);
    let mut prompt = String::new();
    reader.read_line(&mut prompt).expect("读取提示失败");
    print!("{}", prompt);

    // 读取用户输入并传递给子进程
    let stdin = child.stdin.take().unwrap();
    let mut input = String::new();
    io::stdin().read_line(&mut input).expect("读取用户输入失败");
    let mut writer = io::BufWriter::new(stdin);
    writer.write_all(input.as_bytes()).expect("传递输入失败");
    writer.flush().expect("刷新输出缓冲区失败");

    // 读取脚本剩余的输出并显示
    let mut remaining_output = String::new();
    reader.read_to_string(&mut remaining_output).expect("读取剩余输出失败");
    print!("{}", remaining_output);

    // 等待脚本执行完成
    let exit_status = child.wait().expect("等待脚本完成失败");
    println!("脚本退出状态: {}", exit_status);
}

这种方式通过缓冲流读取脚本提示,将用户输入传递给脚本,最后读取剩余输出内容,适合需要对脚本输出做额外处理的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:03:34