You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在子进程Shell中执行命令?Rust能否操控新Shell执行命令?

How to Execute Commands in a Shell Spawned as a Subprocess (Rust Specific)

Great question! Let's break this down clearly to cover both parts of your query:

1. General Ways to Run Commands in a Child Shell

There are two primary patterns here:

  • Single one-off command: Pass the command directly to the shell using the -c flag. This spawns the shell, runs your command, then exits immediately.
  • Persistent interactive session: Spawn a long-running shell process, then send commands to its standard input stream and read results from its output/error streams.

2. Executing Commands in Your Spawned sh Subprocess with Rust

Absolutely! The trick is to redirect the shell's input/output/error streams so your Rust program can communicate with it. Here's a practical example that shows how to do this:

use std::io::{self, Write};
use std::process::{Command, Stdio};

fn main() -> io::Result<()> {
    // Spawn a persistent sh shell with piped streams for interaction
    let mut child = Command::new("sh")
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .stderr(Stdio::piped())
        .spawn()?;

    // Grab handles to the shell's input and output channels
    let mut stdin = child.stdin.take().expect("Couldn't access shell's stdin");
    let mut stdout = child.stdout.take().expect("Couldn't access shell's stdout");

    // Send a command to the shell (don't forget the newline—shells need it to execute!)
    writeln!(stdin, "echo 'Hi from the child shell!'")?;
    // Flush the buffer to make sure the command is sent right away
    stdin.flush()?;

    // Read and print the shell's output
    let mut output = String::new();
    stdout.read_to_string(&mut output)?;
    println!("Shell output:\n{}", output);

    // Send another command if you want
    writeln!(stdin, "pwd")?;
    stdin.flush()?;
    output.clear();
    stdout.read_to_string(&mut output)?;
    println!("Second command output:\n{}", output);

    // Terminate the shell cleanly
    writeln!(stdin, "exit")?;
    stdin.flush()?;

    // Wait for the shell process to finish and check its exit status
    let exit_status = child.wait()?;
    println!("Shell exited with status: {}", exit_status);

    Ok(())
}

Important Details:

  • Stdio::piped(): This creates communication pipes between your Rust program and the child shell, enabling two-way interaction.
  • Newlines: Shells require a newline character to recognize the end of a command—use writeln! or append \n to your command strings.
  • Flushing stdin: The flush() call ensures your command isn't stuck in a buffer and gets sent to the shell immediately.
  • Error handling: The example uses ? for error propagation and expect() for simplicity, but in production code, you’ll want to handle errors gracefully with match or if let statements.

If you only need to run a single command (no persistent shell), a simpler approach works too:

use std::process::Command;

fn main() {
    let output = Command::new("sh")
        .arg("-c")
        .arg("echo 'Quick one-off command!' && ls -la")
        .output()
        .expect("Failed to run command");

    println!("Output:\n{}", String::from_utf8_lossy(&output.stdout));
    if !output.stderr.is_empty() {
        println!("Errors:\n{}", String::from_utf8_lossy(&output.stderr));
    }
}

This spawns the shell, runs your command(s), collects all output, and exits—no ongoing interaction required.

内容的提问来源于stack exchange,提问作者Harshit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 08:23:12