1

I am trying to create a function that installs homebrew by running install.sh using std::process::Command:

let output = Command::new("bash")
    .arg("install.sh")
    .output()
    .expect("brew install failed");

println!("command output: {:?}", output);        

This prints the following output, which is a prompt asking for the user's password, in this case mine.

command output: "==> Checking for `sudo` access (which may request your password).\nNeed sudo access on macOS (e.g. the user blah needs to be an Administrator)!\n"

How do I pass in the password to the command and continue with the installation? Basically, I am looking for a way to emulate the shell script's expect function using the Command struct. Is it possible?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
iismaell
  • 623
  • 5
  • 10
  • 3
    What `expect` does is to allocate a pseudo-terminal (pty) and redirect the reading half it to the stdin of the shell; then it writes the user input to the writing half of the pty. Maybe it is easier just to call `expect` directly or even setup the `sudoers` file to not need a password for this particular command? – rodrigo May 11 '21 at 11:25
  • I would also recommend just shelling out to `expect`, as properly interacting with the two sides (stdin/stdout) of an interactive subprocess tends to be rather tricky. – Masklinn May 11 '21 at 11:42
  • Yes, I have thought of using expect directly and modify the install.sh, but still curious if this is possible with Command. Using the wait_with_output function allows the previous command to proceed and ask for the password, but I would like it to fetch or receive the password automatically and continue with the installation without asking. – iismaell May 11 '21 at 11:45
  • 1
    Yes it's possible: use [`spawn`](https://doc.rust-lang.org/std/process/struct.Command.html#method.spawn) instead of `output`, then use the [`stdin`, `stdout` and `stderr`](https://doc.rust-lang.org/std/process/struct.Child.html#fields) of the returned child to interact with it. – Jmb May 11 '21 at 12:15
  • 1
    Or use the [`rexpect` crate](https://crates.io/crates/rexpect). – Jmb May 11 '21 at 12:18
  • 1
    It appears your question is answered by [Write to child process' stdin in Rust?](https://stackoverflow.com/q/49218599/155423) or [How to send input to a program through stdin in Rust](https://stackoverflow.com/q/21615188/155423) – Shepmaster May 11 '21 at 12:18

0 Answers0