Skip to main content

Bash infrastructure for AI agents

Project description

bashkuto

Alt text

Bashkuto is a lightweight Python library that transforms Bash environments into agent-friendly runtimes. It provides AI agents with safe, structured, and efficient command execution capabilities with built-in safeguards for production use.

Python 3.12+ License: MIT PyPI version GitHub stars GitHub issues GitHub forks CI Status Code style: black Documentation Status


Features

  • Command Execution: Safe subprocess execution with timing and error tracking
  • Pipe Chains: Full support for complex Bash pipelines
  • Overflow Handling: Graceful handling of large outputs with automatic file spill-over and cleanup
  • Binary Guards: Automatic detection and suppression of binary output
  • Structured Output: Multiple output formats optimized for LLM consumption (string, dict, JSON)
  • Security: Regex-based command blocking with customizable allowlists/blocklists
  • Timeout Support: Configurable command timeouts to prevent hanging
  • Cross-Platform: Works on Windows, Linux, and macOS
  • Zero Dependencies: Pure Python 3.12+ with no external requirements

Installation

  pip install bashkuto

For development:

  pip install -e ".[dev]"

Quick Start

from bashkuto import BashRuntime, run

# Simple usage with default runtime
result = run("echo hello")
print(result)
# Output:
# hello
# [exit:0 | 1ms]

# Advanced usage with custom runtime
runtime = BashRuntime(
    timeout_sec=30,
    max_output_chars=8000,
    blocked_substrings=["rm -rf"],
)

result = runtime.run("ls -la")
print(result.output)
print(result.exit_code)
print(result.duration_ms)

API Reference

BashRuntime

Main class for executing bash commands safely.

from bashkuto import BashRuntime

runtime = BashRuntime(
    shell=None,                         # Shell executable (default: platform default)
    timeout_sec=None,                   # Command timeout in seconds
    max_output_chars=8000,              # Max output before truncation
    blocked_substrings=None,            # Additional blocked substrings
    blocked_patterns=None,              # Additional blocked regex patterns
    overflow_dir=".bashkuto_overflow",  # Overflow file directory
    overflow_max_age_hours=24,          # Max age of overflow files
    overflow_max_size_mb=100,           # Max size of overflow directory
    cwd=None,                           # Working directory for commands
    env=None,                           # Environment variables
)

result = runtime.run("your-command")

๐Ÿš Shell Compatibility Note

Bashkuto uses your system's shell executables. For the best experience with BashSession persistence and state tracking:

  • Unix/Linux/macOS: Use POSIX-compliant shells like bash (preferred), sh, or zsh.
  • Windows: Use cmd.exe (preferred).

While other shells like fish or PowerShell can be used for single commands, their unique syntax may interfere with automatic state tracking (like cd persistence) in BashSession.

CommandResult

Dataclass containing command execution results.

@dataclass
class CommandResult:
    output: str              # stdout
    stderr: str              # stderr
    exit_code: int           # Exit code
    duration_ms: int         # Execution duration
    truncated: bool          # Was output truncated?
    overflow_file: str       # Path to overflow file (if any)

Methods:

  • to_agent_string() - Format for LLM consumption (legacy format)
  • to_dict() - Convert to dictionary
  • to_json(indent=2) - Convert to JSON string
  • success property - True if exit_code == 0

OutputFormatter

Format command results for optimal agent consumption.

from bashkuto import OutputFormatter, format_result

formatter = OutputFormatter(max_context_lines=50)
formatted = formatter.format_for_agent(
    result,
    include_stderr=True,
    include_metadata=True,
    compact=False
)

# Or use convenience function
formatted = format_result(result, max_context_lines=50)

Security

Customize security rules:

from bashkuto import BashRuntime, SecurityError

runtime = BashRuntime(
    blocked_substrings=["dangerous_cmd"],
    blocked_patterns=[
        r"rm\s+-rf\s+/",      # Block rm -rf /
        r"curl.*\|\s*sh",     # Block curl | sh
    ]
)

try:
    runtime.run("rm -rf /")
except SecurityError as e:
    print(f"Blocked: {e}")

Exceptions

from bashkuto import (
    BashkutoError,      # Base exception
    SecurityError,      # Security check failed
    TimeoutError,       # Command timed out
    BinaryOutputError,  # Binary output detected
    OverflowError,      # Overflow handling failed
)

Examples

Basic Command Execution

from bashkuto import BashRuntime

runtime = BashRuntime()

# Simple command
result = runtime.run("echo hello")
assert result.success
assert "hello" in result.output

# Pipe chains
result = runtime.run("echo hello | grep hello")
assert result.success

# Failed command
result = runtime.run("false")
assert not result.success
assert result.exit_code == 1

Structured Output

from bashkuto import BashRuntime
import json

runtime = BashRuntime()
result = runtime.run("ls -la")

# Access as dictionary
data = result.to_dict()
print(data["stdout"])
print(data["exit_code"])

# Access as JSON
json_str = result.to_json()
parsed = json.loads(json_str)

# Check success
if result.success:
    print("Command succeeded!")

Timeout Handling

from bashkuto import BashRuntime, TimeoutError

runtime = BashRuntime(timeout_sec=5)

try:
    result = runtime.run("long-running-command")
except TimeoutError as e:
    print(f"Command timed out: {e}")

Output Truncation

from bashkuto import BashRuntime

runtime = BashRuntime(max_output_chars=1000)
result = runtime.run("cat large_file.txt")

if result.truncated:
    print(f"Output truncated, see: {result.overflow_file}")
    # Full output saved to overflow file

Custom Security Rules

from bashkuto import BashRuntime, SecurityError

# Add custom blocked commands
runtime = BashRuntime(
    blocked_substrings=["malicious"],
    blocked_patterns=[
        r"wget.*-O-.*\|.*sh",  # wget | sh
        r"dd\s+.*of=/dev/",    # dd to disk
    ]
)

try:
    runtime.run("malicious_command")
except SecurityError:
    print("Command blocked!")

Security Model

Bashkuto uses a blocklist-based security model:

Default Blocked Commands

  • rm -rf - Recursive force delete
  • :(){ :|:& };: - Fork bomb
  • rm -rf / - Root directory deletion (regex)
  • chmod -R 777 / - Dangerous permissions (regex)
  • > /dev/sd[a-z] - Disk overwriting (regex)
  • mkfs.* - Filesystem creation (regex)
  • dd.*of=/dev/ - Low-level disk writing (regex)
  • shutdown -h now - Immediate shutdown (regex)
  • reboot -f - Force reboot (regex)
  • curl.*|.*sh - Remote script execution (regex)
  • wget.*-O-.*|.*sh - Remote wget execution (regex)

Adding Custom Rules

runtime = BashRuntime(
    blocked_substrings=["custom_cmd"],
    blocked_patterns=[r"dangerous_\w+"],
)

โš ๏ธ Security Warning

Bashkuto runs commands with your user's permissions. For untrusted code:

  • Use containerization (Docker, etc.)
  • Run in a sandboxed environment
  • Implement additional allowlisting
  • Enable audit logging

Logging

Bashkuto uses Python's standard logging:

import logging

logging.basicConfig(level=logging.INFO)
logging.getLogger("bashkuto").setLevel(logging.DEBUG)

from bashkuto import BashRuntime
runtime = BashRuntime()
runtime.run("echo test")  # Logs execution details

Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚         Agent Interface             โ”‚
โ”‚  (api.py - run(), BashRuntime)      โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚        Presentation Layer           โ”‚
โ”‚  (formatter.py, truncation.py,      โ”‚
โ”‚   binary_guard.py)                  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚         Execution Layer             โ”‚
โ”‚  (executor.py, guards.py, result.py,โ”‚
โ”‚   runtime.py)                       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Running Tests

# Install dev dependencies
pip install -e ".[dev]"

# Run all tests
pytest tests/ -v

# Run with coverage
pytest tests/ -v --cov=bashkuto --cov-report=html

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass
  6. Submit a pull request

License

MIT License - see LICENSE file for details.

Author

Mohamed Sofiene Kadri ms.kadri.dev@gmail.com

Acknowledgments

Built for the AI agent community to provide safe, reliable Bash execution environments.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bashkuto-0.1.0.tar.gz (159.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bashkuto-0.1.0-py3-none-any.whl (18.5 kB view details)

Uploaded Python 3

File details

Details for the file bashkuto-0.1.0.tar.gz.

File metadata

  • Download URL: bashkuto-0.1.0.tar.gz
  • Upload date:
  • Size: 159.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.19

File hashes

Hashes for bashkuto-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d22763f54f3bb74e993e7d4a84ceba4836dfd7a815389b9f9388ce0496a48d1a
MD5 ea2bf05790443d7e062b2a584f241aca
BLAKE2b-256 48aaf72747a3a3742a4a392a42953fb865b5276defd1974ab3ef3a860ab7e86b

See more details on using hashes here.

File details

Details for the file bashkuto-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: bashkuto-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 18.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.19

File hashes

Hashes for bashkuto-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ef05e187996c6c70728bed55cdaf299dea95a97f71de15601ea7c46140ddeef2
MD5 ad296dc5e62235840ae809b44c842ee3
BLAKE2b-256 cfe01b128ed83bc21b6ce8d143495d7ca61af7265134c2c68de65e4da620e876

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page