The bash tool enables Claude to execute shell commands in a persistent bash session, allowing system operations, script execution, and command-line automation.
Older tool versions are not guaranteed to be backwards-compatible with newer models. Always use the tool version that corresponds to your model version.
Claude can chain commands to complete complex tasks:
Copy
# User request"Install the requests library and create a simple Python script that fetches a joke from an API, then run it."# Claude's tool uses:# 1. Install package{"command": "pip install requests"}# 2. Create script{"command": "cat > fetch_joke.py << 'EOF'\nimport requests\nresponse = requests.get('https://official-joke-api.appspot.com/random_joke')\njoke = response.json()\nprint(f\"Setup: {joke['setup']}\")\nprint(f\"Punchline: {joke['punchline']}\")\nEOF"}# 3. Run script{"command": "python fetch_joke.py"}
The session maintains state between commands, so files created in step 2 are available in step 3.
The bash tool is implemented as a schema-less tool. When using this tool, you don’t need to provide an input schema as with other tools; the schema is built into Claude’s model and can’t be modified.
1
Set up a bash environment
Create a persistent bash session that Claude can interact with:
Extract and execute commands from Claude’s responses:
Copy
for content in response.content: if content.type == "tool_use" and content.name == "bash": if content.input.get("restart"): bash_session.restart() result = "Bash session restarted" else: command = content.input.get("command") result = bash_session.execute_command(command) # Return result to Claude tool_result = { "type": "tool_result", "tool_use_id": content.id, "content": result }
4
Implement safety measures
Add validation and restrictions:
Copy
def validate_command(command): # Block dangerous commands dangerous_patterns = ['rm -rf /', 'format', ':(){:|:&};:'] for pattern in dangerous_patterns: if pattern in command: return False, f"Command contains dangerous pattern: {pattern}" # Add more validation as needed return True, None
def execute_with_timeout(command, timeout=30): try: result = subprocess.run( command, shell=True, capture_output=True, text=True, timeout=timeout ) return result.stdout + result.stderr except subprocess.TimeoutExpired: return f"Command timed out after {timeout} seconds"
Maintain session state
Keep the bash session persistent to maintain environment variables and working directory:
Copy
# Commands run in the same session maintain statecommands = [ "cd /tmp", "echo 'Hello' > test.txt", "cat test.txt" # This works because we're still in /tmp]
Handle large outputs
Truncate very large outputs to prevent token limit issues: