pub struct Shell { /* private fields */ }Expand description
Builder for executing a shell command.
Supports optional timeout, working directory, environment variables, and
clean-environment mode. Output is truncated to MAX_OUTPUT_SIZE
to prevent OOM on large outputs.
§Security
Commands created with Shell::new are executed via sh -c, which means
shell metacharacters (;, |, $(), `, etc.) are interpreted.
Do not incorporate untrusted input into command strings without proper
validation. Use Shell::env to pass dynamic data safely through
environment variables, or use Shell::exec to bypass shell interpretation
entirely.
§Examples
use std::time::Duration;
use ironflow_core::operations::shell::Shell;
let output = Shell::new("cargo test")
.dir("/path/to/project")
.timeout(Duration::from_secs(120))
.env("RUST_LOG", "debug")
.await?;
println!("stdout: {}", output.stdout());Implementations§
Source§impl Shell
impl Shell
Sourcepub fn new(command: &str) -> Self
pub fn new(command: &str) -> Self
Create a new shell builder for the given command string.
The command is passed to sh -c, so pipes, redirects, and other shell
features work as expected.
§Security
Never interpolate untrusted input directly into the command string. Doing so creates a command injection vulnerability:
// DANGEROUS - attacker controls `user_input`
let _ = Shell::new(&format!("cat {user_input}"));
// SAFE - use arguments via a wrapper script or validate input first
let _ = Shell::new("cat -- ./known_safe_file.txt");If you need to pass dynamic values, either validate them rigorously
or use Shell::env to pass data through environment variables
(which are not interpreted by the shell).
Sourcepub fn exec(program: &str, args: &[&str]) -> Self
pub fn exec(program: &str, args: &[&str]) -> Self
Create a new builder that executes a program directly without shell interpretation.
Unlike Shell::new, this does not pass the command through
sh -c. The program is invoked directly with the given args,
so shell metacharacters in arguments are treated as literal text.
This is the preferred way to run commands with untrusted arguments.
§Examples
use ironflow_core::operations::shell::Shell;
let output = Shell::exec("git", &["log", "--oneline", "-5"]).await?;
println!("{}", output.stdout());Sourcepub fn timeout(self, timeout: Duration) -> Self
pub fn timeout(self, timeout: Duration) -> Self
Override the maximum duration for the command.
If the command does not complete within this duration, it is killed and
an OperationError::Timeout is returned. Defaults to 5 minutes.
Sourcepub fn env(self, key: &str, value: &str) -> Self
pub fn env(self, key: &str, value: &str) -> Self
Add an environment variable to the spawned process.
Can be called multiple times to set several variables.
Sourcepub fn clean_env(self) -> Self
pub fn clean_env(self) -> Self
Clear the inherited environment so the process starts with an empty
environment (plus any variables added via env).
Sourcepub fn dry_run(self, enabled: bool) -> Self
pub fn dry_run(self, enabled: bool) -> Self
Enable or disable dry-run mode for this specific operation.
When dry-run is active, the command is logged but not executed.
A synthetic ShellOutput is returned with empty stdout/stderr,
exit code 0, and 0ms duration.
If not set, falls back to the global dry-run setting
(see set_dry_run).
Sourcepub async fn run(self) -> Result<ShellOutput, OperationError>
pub async fn run(self) -> Result<ShellOutput, OperationError>
Execute the command and wait for it to complete.
§Errors
OperationError::Shell- if the command exits with a non-zero code or cannot be spawned.OperationError::Timeout- if the command exceeds the configuredtimeout.