pub struct Bash { /* private fields */ }Expand description
Main entry point for Bashkit.
Provides a virtual bash interpreter with an in-memory virtual filesystem.
Implementations§
Source§impl Bash
impl Bash
Sourcepub fn builder() -> BashBuilder
pub fn builder() -> BashBuilder
Create a new BashBuilder for customized configuration.
Sourcepub async fn exec(&mut self, script: &str) -> Result<ExecResult>
pub async fn exec(&mut self, script: &str) -> Result<ExecResult>
Execute a bash script and return the result.
This method first validates that the script does not exceed the maximum input size, then parses the script with a timeout, AST depth limit, and fuel limit, then executes the resulting AST.
Sourcepub async fn exec_streaming(
&mut self,
script: &str,
output_callback: OutputCallback,
) -> Result<ExecResult>
pub async fn exec_streaming( &mut self, script: &str, output_callback: OutputCallback, ) -> Result<ExecResult>
Execute a bash script with streaming output.
Like exec, but calls output_callback with incremental
(stdout_chunk, stderr_chunk) pairs as output is produced. Callbacks fire
after each loop iteration, command list element, and top-level command.
The full result is still returned in ExecResult for callers that need it.
§Example
use bashkit::Bash;
use std::sync::{Arc, Mutex};
let chunks: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(Vec::new()));
let chunks_cb = chunks.clone();
let mut bash = Bash::new();
let result = bash.exec_streaming(
"for i in 1 2 3; do echo $i; done",
Box::new(move |stdout, _stderr| {
chunks_cb.lock().unwrap().push(stdout.to_string());
}),
).await?;
assert_eq!(result.stdout, "1\n2\n3\n");
assert_eq!(*chunks.lock().unwrap(), vec!["1\n", "2\n", "3\n"]);Sourcepub fn cancellation_token(&self) -> Arc<AtomicBool> ⓘ
pub fn cancellation_token(&self) -> Arc<AtomicBool> ⓘ
Return a shared cancellation token.
Set the token to true from any thread to abort execution at the next
command boundary with Error::Cancelled.
The caller is responsible for resetting the flag to false before
calling exec() again.
Sourcepub fn fs(&self) -> Arc<dyn FileSystem>
pub fn fs(&self) -> Arc<dyn FileSystem>
Get a clone of the underlying filesystem.
Provides direct access to the virtual filesystem for:
- Pre-populating files before script execution
- Reading binary file outputs after execution
- Injecting test data or configuration
§Example
use bashkit::Bash;
use std::path::Path;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let mut bash = Bash::new();
let fs = bash.fs();
// Pre-populate config file
fs.mkdir(Path::new("/config"), false).await?;
fs.write_file(Path::new("/config/app.txt"), b"debug=true\n").await?;
// Bash script can read pre-populated files
let result = bash.exec("cat /config/app.txt").await?;
assert_eq!(result.stdout, "debug=true\n");
// Bash creates output, read it directly
bash.exec("echo 'done' > /output.txt").await?;
let output = fs.read_file(Path::new("/output.txt")).await?;
assert_eq!(output, b"done\n");
Ok(())
}Sourcepub fn mount(
&self,
vfs_path: impl AsRef<Path>,
fs: Arc<dyn FileSystem>,
) -> Result<()>
pub fn mount( &self, vfs_path: impl AsRef<Path>, fs: Arc<dyn FileSystem>, ) -> Result<()>
Mount a filesystem at vfs_path on a live interpreter.
Unlike BashBuilder mount methods which configure mounts before build,
this method attaches a filesystem after the interpreter is running.
Shell state (env vars, cwd, history) is preserved — no rebuild needed.
The mount takes effect immediately: subsequent exec() calls will see
files from the mounted filesystem at the given path.
§Arguments
vfs_path- Absolute path where the filesystem will appear (e.g./mnt/data)fs- The filesystem to mount
§Errors
Returns an error if vfs_path is not absolute.
§Example
use bashkit::{Bash, FileSystem, InMemoryFs};
use std::path::Path;
use std::sync::Arc;
let mut bash = Bash::new();
// Create and populate a filesystem
let data_fs = Arc::new(InMemoryFs::new());
data_fs.write_file(Path::new("/users.json"), br#"["alice"]"#).await?;
// Mount it live — no rebuild, no state loss
bash.mount("/mnt/data", data_fs)?;
let result = bash.exec("cat /mnt/data/users.json").await?;
assert!(result.stdout.contains("alice"));Sourcepub fn unmount(&self, vfs_path: impl AsRef<Path>) -> Result<()>
pub fn unmount(&self, vfs_path: impl AsRef<Path>) -> Result<()>
Unmount a previously mounted filesystem.
After unmounting, paths under vfs_path fall back to the root filesystem
or the next shorter mount prefix. Shell state is preserved.
§Errors
Returns an error if nothing is mounted at vfs_path.
§Example
use bashkit::{Bash, FileSystem, InMemoryFs};
use std::path::Path;
use std::sync::Arc;
let mut bash = Bash::new();
let tmp_fs = Arc::new(InMemoryFs::new());
tmp_fs.write_file(Path::new("/data.txt"), b"temp").await?;
bash.mount("/scratch", tmp_fs)?;
let result = bash.exec("cat /scratch/data.txt").await?;
assert_eq!(result.stdout, "temp");
bash.unmount("/scratch")?;
// /scratch/data.txt is no longer accessibleSourcepub fn shell_state(&self) -> ShellState
pub fn shell_state(&self) -> ShellState
Capture the current shell state (variables, env, cwd, options).
Returns a serializable snapshot of the interpreter state. Combine with
InMemoryFs::snapshot() for full session persistence.
§Example
use bashkit::Bash;
let mut bash = Bash::new();
bash.exec("x=42").await?;
let state = bash.shell_state();
bash.exec("x=99").await?;
bash.restore_shell_state(&state);
let result = bash.exec("echo $x").await?;
assert_eq!(result.stdout, "42\n");Sourcepub fn restore_shell_state(&mut self, state: &ShellState)
pub fn restore_shell_state(&mut self, state: &ShellState)
Restore shell state from a previous snapshot.
Restores variables, env, cwd, arrays, aliases, traps, and options. Does not restore functions or builtins — those remain as-is.