Skip to content

elixir-ai-tools/just_bash

Repository files navigation

JustBash

A simulated bash environment with an in-memory virtual filesystem, written in Elixir.

Designed for AI agents that need a secure, sandboxed bash environment.

Supports optional network access via curl with secure-by-default URL filtering.

Note: This is an Elixir port of just-bash by Vercel. The entire codebase was generated through conversational prompting with Claude Opus 4.5 via OpenCode.

Security Model

  • The shell only has access to the provided virtual filesystem
  • No access to the real filesystem by default
  • No network access by default
  • Network access can be enabled with URL allowlists

Installation

def deps do
  [{:just_bash, "~> 0.1.0"}]
end

Usage

Basic API

bash = JustBash.new()
{result, _} = JustBash.exec(bash, ~s(echo "Hello" > greeting.txt))
{result, _} = JustBash.exec(bash, "cat greeting.txt")
result.stdout  #=> "Hello\n"
result.exit_code  #=> 0

Configuration

bash = JustBash.new(
  files: %{"/data/file.txt" => "content"},  # Initial files
  env: %{"MY_VAR" => "value"},              # Environment variables
  cwd: "/app"                                # Starting directory
)

Network Access

Network access is disabled by default. Enable it with allowlists:

# Allow specific hosts
bash = JustBash.new(
  network: %{
    enabled: true,
    allow_list: ["api.github.com", "*.example.com"]
  }
)

# Custom HTTP client for testing
bash = JustBash.new(
  network: %{enabled: true},
  http_client: MyMockHttpClient
)

Execute Script Files

# Run a script from the real filesystem in the sandbox
{result, bash} = JustBash.exec_file("script.sh")

# With options
JustBash.exec_file("script.sh",
  files: %{"/data/input.txt" => "hello"},
  network: %{enabled: true}
)

Sigil

import JustBash.Sigil

result = ~b"echo hello"
result.stdout  #=> "hello\n"

# Modifiers
~b"echo hello"t  # trimmed output
~b"echo hello"s  # stdout only
~b"exit 42"e     # exit code

Supported Commands

File Operations

cat, cp, file, find, ln, ls, mkdir, mv, readlink, rm, stat, touch, tree, du

Text Processing

awk, base64, comm, cut, diff, expand, fold, grep, head, md5sum, nl, paste, rev, sed, sort, tac, tail, tr, uniq, wc, xargs

Data Processing

jq (JSON), markdown (Markdown → HTML)

Network

curl

Shell Builtins

echo, printf, cd, pwd, export, unset, set, test, [, [[, true, false, :, source, ., read, exit, return, local, declare, break, continue, shift, getopts, trap

Utilities

basename, dirname, date, env, hostname, printenv, seq, sleep, tee, which

Shell Features

  • Pipes: cmd1 | cmd2
  • Redirections: >, >>, 2>, &>, <, <<<, heredocs
  • Command chaining: &&, ||, ;
  • Variables: $VAR, ${VAR}, ${VAR:-default}, ${VAR:=value}, ${#VAR}, ${VAR:start:len}, ${VAR#pattern}, ${VAR%pattern}, ${VAR/old/new}, ${VAR^^}, ${VAR,,}
  • Brace expansion: {a,b,c}, {1..10}, {a..z}
  • Arithmetic: $((expr)) with full operators
  • Glob patterns: *, ?, [...]
  • Control flow: if/elif/else/fi, for/while/until, case/esac
  • Functions: function name { ... } or name() { ... }
  • Arrays: arr=(...), ${arr[0]}, ${arr[@]}, ${#arr[@]}
  • Subshells: (cmd) and command groups { cmd; }

Default Layout

When created without options, JustBash provides a Unix-like directory structure:

  • /home/user - Default working directory (and $HOME)
  • /bin, /usr/bin - Binary directories
  • /tmp - Temporary files

API Reference

# Create environment
bash = JustBash.new(opts)

# Execute command
{result, bash} = JustBash.exec(bash, "command")
result.stdout      # String
result.stderr      # String
result.exit_code   # Integer
result.env         # Updated environment

# Parse without executing
{:ok, ast} = JustBash.parse("echo hello")

# Format script
{:ok, formatted} = JustBash.format("if true;then echo yes;fi")

Development

mix deps.get
mix test           # 2400+ tests
mix dialyzer       # Type checking
mix credo          # Linting

License

MIT

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published