如何调用系统命令并捕获其输出?

172

在Rust中是否有一种调用系统命令(如lsfuser)的方法?能否捕获其输出?

4个回答

204

std::process::Command可以实现这一点。

有多种方法可以生成一个子进程并在计算机上执行任意命令:

  • spawn — 运行程序并返回包含详细信息的值
  • output — 运行程序并返回输出
  • status — 运行程序并返回退出码

以下是文档中的一个简单示例:

use std::process::Command;

Command::new("ls")
        .arg("-l")
        .arg("-a")
        .spawn()
        .expect("ls command failed to start");

11
如果我需要实时输出,我该怎么办?我认为output函数会在进程完成后返回Vec。那么,如果我们运行类似于Command("ping google.com")这样的命令,是否有可能获取此命令的输出,因为它不会完成但我想要打印它的日志。请建议。 - GrvTyagi
7
@GrvTyagi:在这个答案中提到的spawn,会返回一个带有标准I/O流的Child结果。 - Ry-
3
基于这个出色的答案,我也发现这个答案对于理解如何与stdin/stdout交互非常有帮助。 - Michael Noguera

97

来自文档的一个非常清晰的例子:

use std::process::Command;
let output = Command::new("/bin/cat")
                     .arg("file.txt")
                     .output()
                     .expect("failed to execute process");

println!("status: {}", output.status);
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));

assert!(output.status.success());

10

确实是可能的!相关模块是 std::run

let mut options = std::run::ProcessOptions::new();
let process = std::run::Process::new("ls", &[your, arguments], options);

ProcessOptions的标准文件描述符默认为None(创建一个新管道),所以你可以直接使用process.output()(例如)来读取其输出。

如果你想要运行命令并在完成后获取所有输出,可以使用wait_with_output

顺便说一下,截至昨天,Process::new现在返回的是Option<Process>而不是Process


14
现在在 rustc 1.19.0 中,它已经变成了 std::process - WiSaGaN

0

命令 构建并配置子进程。当您创建 Command 的新实例并指定要执行的命令、任何参数、环境变量和其他设置时,您正在定义一个子进程的配置。

use std::process::{Command, Stdio};

let system_command = "echo";
let argument = "Hello World";

let echo_hello: std::process::Output = Command::new(system_command)
                        .arg(argument)
                        //.current_dir(TEST_PATH)
                        // Stdio::piped() creates pipes to capture stdout and stderr of a child process which is created by Command. 
                        // we are telling the Command to create a pipe to capture the standard output (stdout) of the child process.
                        .stdout(Stdio::piped())
                        // creating a pipe to capture the standard error (stderr) of the child process.
                        .stderr(Stdio::piped())
                        // output() executes the child process synchronously and captures its output. 
                        //It returns a std::process::Output struct containing information about the process's exit status, stdout, and stderr.
                        .output()
                        .expect("Failed to echo");

你可以使用spawn()而不是output()来异步执行子进程。使用spawn()将允许子进程独立运行,与父进程无关。spawn()返回结果。
std::process::Child 

如果由于某种原因需要提前终止子进程,可以在 std::process::Child 句柄上调用 kill() 方法。另一方面,一旦调用了 output() 方法,子进程将运行至完成,并且 output() 不提供直接的机制来提前终止进程。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接