I want to use Rust to create a specialized chess analysis program that will interact with one of the best existing chess programs in the world (Stockfish) as a subprocess. I could need to communicate with that sub-process about 100 times per chess game I want to analyze. Based on the following I was able to successfully communicate with the Stockfish sub-process once: Pipes - Rust By Example
I changed the command as necessary and then sent the input "uci" and got a couple of dozens of lines of output back just like I would on the command line:
id name Stockfish 11 64
id author T. Romstad, M. Costalba, J. Kiiski, G. Linscott
....
....
option name SyzygyProbeDepth type spin default 1 min 1 max 100
option name Syzygy50MoveRule type check default true
Now I would like to send more input to the pipe, next specifically "isready" (to which the response should be "readyok"). However the comments in the code I'm emulating specifically say "stdin
does not live after the above calls...the pipe is closed".
I did find the following on stackoverflow command - Unable to pipe to or from spawned child process more than once - Stack Overflow and tried modifiying it to my purpose albeit without success: My idea is to put what I want to send to stdin into an array (or I could change it to vector) and then loop over that. I'm starting with just the 4 data I want to initially pass to the process, there could potentially be dozens more.
use std::process::{Command, Stdio};
use std::io::{BufRead, Write, BufReader};
fn main() {
const INIT_INPUT: [&'static str; ] = ["uci", "isready", "position startpos", "go infinite"];
let mut child_shell = Command::new("opt/stockfish_20011801_x64")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap();
let child_in = child_shell.stdin.as_mut().unwrap();
let mut child_out = BufReader::new(child_shell.stdout.as_mut().unwrap());
let mut line = String::new();
for process_input in INIT_INPUT.iter() {
println!("{}", process_input);
// child_in.write(process_input.as_bytes()).unwrap();
// while child_out.read_line(&mut line).unwrap() != 0 {
// println!("{}", line);
// }
}
}
As it stands, with the input I want to send commented out, it performs as expected, printing to the console the 4 lines of input specified in the array. But if you comment that code in, I get back just one line of output and it does not proceed to the input that I want to send to the pipe.
The stackoverflow Q/A is almost 5 years old, I wonder if there is a more up-to-date way of doing things. Thanks in advance.