Passing input to child process while parent process waits

I am trying to create a new next.js project using Rust Command I expect the child process to take the input and the parent process to wait until the child process exits but I am finding it difficult to do this any help would be appreciated.

        let first_command = "npx";
        let rest_of_commands = vec!["create-next-app@latest", "my-app"];
        
        let mut child = std::process::Command::new(first_command)
            .args(rest_of_commands)
            .stdin(process::Stdio::piped())
            .stdout(process::Stdio::inherit())
            .stderr(process::Stdio::inherit())
            .spawn()?;
        
        let mut stdin_handle = child.stdin.take().unwrap();
        
        thread::spawn(move || -> io::Result<()> {
            let stdin = io::stdin();
            let mut buffer = String::new();
            stdin.read_line(&mut buffer)?;
            stdin_handle.write_all(buffer.as_bytes())?;
            Ok(())
        });

Specifically how? What is the code you posted trying to do, and what does it do instead?

I am sorry if that was unclear, let me give some context, I am creating a CLI app that quickly creates templates, but soon realized that some templates can be the commands that create a project for example to create a Next.js project we have to enter command npx create-next-app@latest project-name which will prompt for the user input for various things, like would you want to use src directory would you want to use eslint as the linter, etc.

I want the CLI to that takes input from the user and shows output back to the user, but since I am doing this by using Command which runs the command in a child process, the parent process immediately exits, I want it to wait.

Either that happens or the program just stops and does not give any output or anything the cli is just stuck right there without anything happening, I have no idea how to go about this. I tried using threads but I could not figure out the right way to do this.

This is how the command asks the questions via stdin

In this particular case, Create Next App | Next.js shows how to run the program non-interactively, which might solve the initial problem. Beyond that, controlling interactive programs is difficult and sometimes requires in-depth knowledge of how PTYs and process groups work, and I would be very tempted to write that part using the “Expect” tool that’s part of Tcl.

To answer the question about the program, it’s the main thread’s responsibility to wait for each spawned thread to complete somehow, like by calling join(), as shown in the examples in the documentation. I don’t think spawning a separate thread is necessary at all if you’re using .stdout(process::Stdio::inherit()), though.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.