如何让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
相关产品推荐
相关产品推荐

