执行一个shell命令

25

我想在 Rust 中执行一个 shell 命令。在 Python 中可以这样做:

import os
cmd = r'echo "test" >> ~/test.txt'
os.system(cmd)

但 Rust 只有 std::process::Command。如何执行像 cd xxx && touch abc.txt 这样的 shell 命令?

3个回答

38

每个人都在寻找:

use std::process::Command;

fn main() {
    let output = Command::new("echo")
        .arg("Hello world")
        .output()
        .expect("Failed to execute command");

    assert_eq!(b"Hello world\n", output.stdout.as_slice());
}

要获取更多信息和示例,请参阅文档

您想模拟 &&std::process::Command 具有返回Result<T>status方法,而 Result 实现了and_then。 您可以像使用 && 一样使用 and_then,但以更安全的Rust方式 :)


5
除非使用Command::new("cd").arg("foo").status().success(),否则Command::new("cd").arg("foo").status()将总是失败的。 - Jmb
1
@Jmb 你知道为什么吗? - S.R
8
因为cd不是一个可执行文件,而是一个内部的shell命令,所以不能直接从非shell程序中运行它。你可以使用 Command::new ("/bin/sh").args (&["-c", "cd", "foo"]) 在shell中运行该命令,但这只是一个无操作(no-op)操作,不会影响调用进程。 - Jmb
那对我没用,我收到了一个运行时错误。当我在Windows上运行时,我不得不执行Command :: new(“cmd”),这样代码就可以正常运行了。 - Gloat
@Jmb 哇,这是一个寻找问题的绝佳答案,我知道我经常遇到这样的问题(cd不是可执行文件或类似的问题),但简洁地解释使它变得非常清晰。 - Félix Adriyel Gagnon-Grenier

9
你应该尽量避免使用“system”。它的功能取决于所用的shell和操作系统(在Windows上,你的示例几乎肯定无法达到预期效果)。
如果你真的非常需要使用shell来调用一些命令,可以直接执行shell(例如使用bash的-c开关),这样会稍微好一点。
如果由于某种原因以上方法不可行,并且你可以保证程序只在特定的系统中运行且用户不会运行其他任何东西...

如果您想要在编程中使用libc,那么您可以像在普通的C语言中一样使用system调用。这被视为FFI,因此您可能需要查看std::ffi::CStr


3

对于任何想设置子进程运行命令的当前目录(比如在某个目录下运行“ls”)的人,可以使用Command::current_dir。用法:

use std::process::Command;

Command::new("ls")
        .current_dir("/bin")
        .spawn()
        .expect("ls command failed to start");

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