Skip to main content

Shell

Struct Shell 

Source
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

Source

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).

Source

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());
Source

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.

Source

pub fn dir(self, dir: &str) -> Self

Set the working directory for the spawned process.

Source

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.

Source

pub fn clean_env(self) -> Self

Clear the inherited environment so the process starts with an empty environment (plus any variables added via env).

Source

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).

Source

pub async fn run(self) -> Result<ShellOutput, OperationError>

Execute the command and wait for it to complete.

§Errors

Trait Implementations§

Source§

impl IntoFuture for Shell

Source§

type Output = Result<ShellOutput, OperationError>

The output that the future will produce on completion.
Source§

type IntoFuture = Pin<Box<dyn Future<Output = <Shell as IntoFuture>::Output> + Send>>

Which kind of future are we turning this into?
Source§

fn into_future(self) -> Self::IntoFuture

Creates a future from a value. Read more

Auto Trait Implementations§

§

impl Freeze for Shell

§

impl RefUnwindSafe for Shell

§

impl Send for Shell

§

impl Sync for Shell

§

impl Unpin for Shell

§

impl UnsafeUnpin for Shell

§

impl UnwindSafe for Shell

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more