Bash Tool¶
Every tool in Amplifier is designed for a specific job — reading files, searching code, navigating symbols. But sometimes you just need to run a shell command. That's what the Bash tool is for: a general-purpose fallback that gives you direct access to the shell when no specialized tool fits.
The key word there is fallback. Amplifier's specialized tools are almost always a better choice — they have structured output, better error handling, and domain-specific intelligence built in. Bash is for everything else: running your test suite, installing a package, checking git status, or spinning up a dev server.
Core Capabilities¶
The Bash tool takes three parameters:
- command (required) — the shell command to execute
- timeout (default: 30 seconds) — how long to wait before killing the process
- run_in_background (default: false) — returns immediately with a PID instead of waiting
That's it. Simple by design — the complexity lives in what you ask it to do.
Running Commands¶
Most of the time, you just ask Amplifier to do something and it reaches for bash when appropriate:
Run the test suite
[Tool: bash] pytest tests/ --verbose
===== test session starts =====
tests/test_auth.py::test_login PASSED
tests/test_auth.py::test_logout PASSED
tests/test_api.py::test_create_user PASSED
===== 3 passed in 1.42s =====
Install the requests library
[Tool: bash] pip install requests
Successfully installed requests-2.31.0
What branch am I on?
[Tool: bash] git branch --show-current
feature/auth-redesign
Notice that you're speaking naturally — Amplifier decides when bash is the right tool and formulates the command for you.
When to Use Bash (and When Not To)¶
This is the most important thing to understand about the Bash tool. Amplifier has specialized tools that do many things better than raw shell commands. Here's the decision matrix:
| Task | Best tool | Why not bash? |
|---|---|---|
| Run tests, builds | Bash | This is bash's sweet spot |
| Install packages | Bash | pip, npm, cargo — all bash territory |
| Git status, diff, commit | Bash | Simple git ops work great here |
| Read a file | read_file | Structured output with line numbers |
| Search file contents | grep | Regex-aware, respects .gitignore, paginated |
| Find files by name | glob | Faster, handles exclusions automatically |
| Fetch a web page | web_fetch | Handles encoding, size limits, save-to-file |
| Complex git workflows | git-ops agent | Multi-step reasoning about branches and merges |
The rule of thumb: if Amplifier has a dedicated tool for the job, use it. Reach for bash when you need to run an actual program — a test runner, a build system, a package manager, a container tool.
Timeouts and Long-Running Commands¶
By default, commands time out after 30 seconds. That's fine for git status or pip install, but a full test suite or a production build needs more room:
Run the full integration test suite
[Tool: bash] pytest tests/integration/ --verbose
timeout: 300
===== 47 passed, 2 skipped in 4m 12s =====
Here's the general guidance:
- 30s (default) — quick commands: git status, ls, pip install a single package
- 120–300s — builds and test suites: pytest, cargo build, npm run build
- run_in_background — anything that runs indefinitely: dev servers, file watchers
Background Processes¶
Some commands aren't meant to finish — dev servers, file watchers, database processes. Use run_in_background to start them without blocking your session:
Start the Next.js dev server
[Tool: bash] npm run dev
run_in_background: true
Started background process with PID 48291
The process runs independently and Amplifier returns immediately. You can check on it later or stop it:
Is the dev server still running?
[Tool: bash] ps aux | grep "npm run dev"
user 48291 0.5 1.2 npm run dev
Stop the dev server
[Tool: bash] kill 48291
Background mode is perfect for:
- Development servers (npm run dev, python manage.py runserver)
- File watchers (cargo watch, nodemon)
- Local databases (redis-server, mongod)
Don't use it for commands where you need the output — test results, build logs, or anything with an exit code you care about.
Output Truncation¶
When a command produces a lot of output, Amplifier automatically truncates it to prevent flooding the conversation context. You'll see something like this:
[Tool: bash] find . -name "*.py" -type f
./src/main.py
./src/config.py
./src/utils/helpers.py
[...truncated...]
./tests/test_integration.py
./tests/conftest.py
[Truncated: showing 2000 of 5234 lines, 45KB of 180KB total]
The truncation shows the first lines, a [...truncated...] marker, and the last lines, plus byte counts so you know what you're missing.
Warning: If the output contains JSON, XML, or other structured data, truncation can break it mid-structure. The workaround is to redirect to a file:
Get the full API response
[Tool: bash] curl https://api.example.com/data > response.json
[Tool: read_file] response.json (lines 1-50)
Redirect first, then read the file in controlled chunks.
Safety Guardrails¶
The Bash tool blocks destructive commands that could damage your system — things like rm -rf / or sudo rm -rf. It also doesn't support interactive commands that wait for user input. Editors like vim, interactive REPLs, and commands without -y flags will hang and eventually time out.
The fix is usually straightforward — add non-interactive flags:
Initialize a new npm project
[Tool: bash] npm init -y
Wrote to /home/user/project/package.json
The -y flag accepts all defaults without prompting.
Practical Patterns¶
Chaining Commands¶
Use && to chain dependent commands — if any step fails, the rest don't run:
Set up a new Python virtual environment and install dependencies
[Tool: bash] python -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt
Avoid ; for chaining — it runs every command regardless of failures, which can leave you in a messy state.
Quoting Paths¶
Always quote paths that might contain spaces:
# Works
cd "/home/user/My Projects/webapp"
# Breaks — shell sees three arguments
cd /home/user/My Projects/webapp
Absolute vs. Relative Paths¶
Prefer absolute paths when you're unsure of the working directory. Each bash invocation maintains its directory context within a session, but absolute paths remove all ambiguity:
# Unambiguous
pytest /home/user/project/tests/
# Depends on where you are
pytest tests/
Redirecting Large Output¶
When a command generates more output than you need in context, redirect and then inspect:
> Show me just the failing tests from the full suite
[Tool: bash] pytest tests/ --tb=short 2>&1 | grep -E "FAILED|ERROR"
tests/test_api.py::test_timeout FAILED
tests/test_api.py::test_retry ERROR
Piping through grep keeps the output focused and avoids truncation.
Tips¶
- Increase timeout for builds. A 30-second default is too short for
cargo build --releaseornpm run build. Bump to 120–300 seconds. - Redirect structured output. If a command returns JSON or XML, save to a file first:
command > output.json. Then useread_fileto inspect it. - Check before you chain. Run
which pytestorpython --versionbefore a long chain — catching a missing tool early saves time. - Use background for servers, not builds. You want to see build output. You don't want to wait for a server to "finish."
- Pipe to filter. Combine bash with
grep,head,tail, orwcto keep output manageable within a single command.
Next Steps¶
- Learn about the Filesystem Tool for reading and editing files — the preferred alternative to
catandsedvia bash - Explore Search Tools to see why
grepandglobbeatfind | xargs grep - See Task (Sub-Agents) for delegating complex work to specialized agents