执行任何 bash 命令,立即获取 stdout/stderr 结果并使用 stdin

x4r*_*rkz 3 process exec rust output

我想执行任何 bash 命令。我发现Command::new但我无法执行“复杂”命令,例如ls ; sleep 1; ls. 此外,即使我将其放入 bash 脚本中并执行它,我也只会在脚本末尾得到结果(正如流程文档中所解释的那样)。我希望在命令打印后立即得到结果(并且也能够读取输入),就像我们在 bash 中一样。

mca*_*ton 7

Command::new确实是要走的路,但它是为了执行一个程序。ls ; sleep 1; ls不是一个程序,它是一些 shell 的指令。如果你想执行类似的事情,你需要让 shell 为你解释它:

Command::new("/usr/bin/sh").args(&["-c", "ls ; sleep 1; ls"])
// your complex command is just an argument for the shell
Run Code Online (Sandbox Code Playgroud)

要获得输出,有两种方法:

  • output方法是阻塞的,并返回命令的输出和退出状态。
  • spawn方法是非阻塞的,并返回一个包含子进程的句柄stdinstdout因此stderr您可以与子进程进行通信,并返回一个wait等待其干净退出的方法。请注意,默认情况下,子级继承其父级文件描述符,您可能需要设置管道:

你应该使用类似的东西:

let child = Command::new("/usr/bin/sh")
                .args(&["-c", "ls  sleep 1 ls"])
                .stderr(std::process::Stdio::null()) // don't care about stderr
                .stdout(std::process::Stdio::piped()) // set up stdout so we can read it
                .stdin(std::process::Stdio::piped()) // set up stdin so we can write on it
                .spawn().expect("Could not run the command"); // finally run the command

write_something_on(child.stdin);
read(child.stdout);
Run Code Online (Sandbox Code Playgroud)