# bash > Execute a shell command in the session workspace, with optional PTY or background-job handling. ## Source - Entry: `packages/coding-agent/src/tools/bash.ts` - Model-facing prompt: `packages/coding-agent/src/prompts/tools/bash.md` - Key collaborators: - `packages/coding-agent/src/tools/bash-interactive.ts` — PTY/TUI execution path. - `packages/coding-agent/src/tools/bash-interceptor.ts` — blocks tool-better shell patterns. - `packages/coding-agent/src/tools/bash-skill-urls.ts` — expands internal URLs to paths. - `packages/coding-agent/src/tools/bash-pty-selection.ts` — `canUseInteractiveBashPty()` decides whether a call may use the local PTY overlay. - `packages/coding-agent/src/tools/gh-cache-invalidation.ts` — drops `github-cache` rows for mutating `gh issue`/`gh pr` subcommands. - `packages/coding-agent/src/exec/bash-executor.ts` — non-PTY shell execution. - `packages/coding-agent/src/session/streaming-output.ts` — tail buffer, truncation, artifact spill. - `packages/coding-agent/src/tools/tool-timeouts.ts` — timeout clamp bounds. - `packages/coding-agent/src/config/settings-schema.ts` — default interceptor rules. - `docs/bash-tool-runtime.md` — deeper executor/runtime notes; use as the companion doc for shell-session internals. ## Inputs | Field | Type | Required | Description | | --- | --- | --- | --- | | `command` | `string` | Yes | Shell command text to execute. A leading `cd && ...` is rewritten into `cwd` only when `cwd` was omitted. | | `env` | `Record` | No | Extra environment variables. Keys must match `^[A-Za-z_][A-Za-z0-9_]*$` or the tool throws. Values go through internal-URL expansion and are passed as environment values, not shell text. | | `timeout` | `number` | No | Timeout in seconds. Default `300`; clamped to `1..3600` by `clampTimeout("bash", ...)`. | | `cwd` | `string` | No | Working directory, resolved against `session.cwd` via `resolveToCwd`. Must exist and be a directory. | | `pty` | `boolean` | No | Request PTY mode. Default `false`. PTY is used only when `pty: true`, `PI_NO_PTY !== "1"`, and the tool context has a UI. | | `async` | `boolean` | No | Background execution request. Present only when `async.enabled` is true for the session. Returns immediately with a job id instead of waiting; it does not extend the effective `timeout`, so jobs are still killed after the clamped `1..3600` second budget. | ## Outputs The tool returns a single `text` content block plus optional `details`. - Success, foreground: - `content[0].text`: command output, or `(no output)` when the command produced nothing. - `details.timeoutSeconds`: effective timeout after clamping. - `details.requestedTimeoutSeconds`: present when the requested timeout differed from the effective timeout. - `details.wallTimeMs`: elapsed wall-clock milliseconds for completed local/client-terminal runs. - `details.terminalId`: present when execution was routed through a client terminal bridge. - `details.exitCode`: present when the command completed with a non-zero exit code. - `details.meta.truncation`: present when output was truncated in memory; includes `artifactId` when full output spilled to an artifact. - non-zero exits return a tool result marked `isError` with output plus `Command exited with code `; they are not thrown. - Success, background start (`async: true` or auto-background): - `content[0].text`: optional preview tail, timeout notice if any, then `Background job started: