description: "The model-facing bash tool for users and maintainers choosing, configuring, or debugging one-shot command execution, background jobs, and sandbox escalation."
English | 中文
dsh-tool-bash lets an agent run one-shot bash commands and receive stdout, stderr, and exit markers. Each call uses a fresh shell, so cwd, variables, and functions do not persist; run_in_background starts long-running work that the agent can inspect with job_output and stop with job_kill. Commands receive the managed DSH_* environment, and sandbox denials can be retried once with wider sandbox_permissions, a justification, and user approval. Non-zero exits are reported as results, so the agent decides how to respond; use an executor such as dsh-bash-local or dsh-bash-sandbox and load dsh-shell-env.
Load this plugin in any composition where the agent should run bash commands: it registers the bash tool once an executor provider and the dsh-shell-env registry are mounted, and stays pending until the tools, shell, systemPrompt, and shellEnv services exist.
The common path is an executor provider, the environment registry, and this tool; add the job runtime when the agent may run commands in the background.
- name: '@deepseek-ai/dsh-bash-local'
- name: '@deepseek-ai/dsh-shell-env'
- name: '@deepseek-ai/dsh-tool-bash'
# Optional: background jobs
- name: '@deepseek-ai/dsh-jobs-local'
- name: '@deepseek-ai/dsh-tool-jobs'
The single config field toggles background support.
| Field | Default | Meaning |
|---|---|---|
enableRunInBackground |
true |
Expose run_in_background; when false, forced background calls are rejected |
The generated configuration catalog is the exhaustive source for every accepted field and its JSDoc; the generated tool catalog carries the full argument schema.
The tool executes bash -c <command> and returns the combined output. Commands run in a fresh shell every call, so state never persists — pass workdir instead of cd. A non-zero exit is reported as [exit code: N] for the agent to interpret, not surfaced as a tool error. A description in active voice (5–10 words) labels the call in the UI; timeoutMs overrides the executor's default and cap. Output beyond the executor's stream caps is truncated to its tail, with the full output saved to a spill file whose path is reported.
Passing run_in_background: true admits a job and returns its id immediately; confinement preparation may still be pending, and no background execution timeout applies. Output is empty until the process is available. Job cancellation aborts preparation and stops any process that arrives afterward; startup failure settles the admitted job as failed. The agent reads its output with job_output (non-blocking unless wait: true), lists jobs with job_list, and stops it with job_kill; a finished job notifies the owning agent in-session. Background support needs the generic job runtime (dsh-jobs-local) and its control tools (dsh-tool-jobs) mounted.
When the mounted executor confines commands (for example dsh-bash-sandbox), a blocked file operation is reported as [sandbox: file access denied under <mode> mode] — a policy denial, not a command failure. The model may then retry the exact same command once in the same turn with sandbox_permissions (the narrowest wider mode that suffices) and a one-sentence justification; the approval prompt raised by that retry is how the user consents. Request wider access only after a real denial; a rejected escalation is final for that command. Repeating the current mode runs without approval, while a narrower target fails before execution.
A composition with no executor provider never activates the tool. Background calls without the job runtime fail with background jobs unavailable: load @deepseek-ai/dsh-jobs and @deepseek-ai/dsh-tool-jobs, and sandbox_permissions without a sandboxing executor fails with sandbox_permissions is not available in this composition (no sandboxing executor to escalate). enableRunInBackground: false removes the parameter and rejects a forced background call at execution time.
Read these pages when the package-level contract is not enough. They move from the shell family to the executor seam, the job runtime, and the decision notes behind the behavior.
DSH_* environment every call receives.job_output, job_list, and job_kill controls for background runs.bash argument schema.Every request in this plugin's registration scope contains the bash guidance below at first-party order 1000. The policy owner contributes current sandbox state through its cache-safe runtime context rather than changing this section. Scoped tool restrictions can hide the schema without removing this independently registered section.
Check the [exit code: N] marker on every bash result; investigate failures before moving on.
Small fixed input cost per request while the plugin is active, unchanged by sandbox mode or mode switches.
Prefix-stable while the registration scope and prompt text are unchanged. Plugin activation or disposal may invalidate reuse from this prompt section; sandbox mode switches do not.
The model sees the generated bash schema. run_in_background appears only when this producer enables it; sandbox_permissions and justification appear only when the mounted executor advertises sandboxing. Agent-scoped tool restrictions can remove the definition for that agent.
Fixed schema cost on every request where the tools are visible; sandbox support adds the escalation fields and its conditional description paragraph.
Prefix-stable while visibility, background support, and executor sandbox capabilities are unchanged. A restriction, config change, or executor change may invalidate reuse from the first changed tool definition.
The renderer emits the data-dependent stdout tail, then optional [stderr] and the stderr tail. With no output it emits exactly (no output). Conditional lines are exactly [output truncated; full output: <path-or-(unavailable)>], [sandbox: file access denied under <mode> mode], [timed out after <timeoutMs>ms], [killed by signal: <signal>], and [exit code: <exitCode>]; the sandbox escalation and runner-failure lines are quoted in dsh-bash-sandbox.
Zero result tokens before a call. Output is bounded per stream, while each emitted line remains in history until compaction.
Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
Start returns exactly started background job <jobId>. This producer supplies incremental process output, optional [some output was dropped from memory; full output: <paths-or-(unavailable)>], sandbox facts, and terminal detail such as exit code: <exitCode> or signal: <signal> to the generic job runtime. dsh-tool-jobs owns the visible status line, completion notice, listing, and cancellation response.
The start acknowledgement is small and retained; collected output is data-dependent and bounded by the executor's stream buffers. Consuming reads do not repeat prior output.
Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
Validation and policy failures are normalized as Error: <message>. This package's stable messages are invalid command: expected a non-empty string, invalid description: expected a non-empty string, invalid timeoutMs: expected a positive number, got <value>, the escalation pairing failures, run_in_background is disabled for this deployment (enableRunInBackground: false), background jobs unavailable: load @deepseek-ai/dsh-jobs and @deepseek-ai/dsh-tool-jobs, sandbox_permissions is not available in this composition (no sandboxing executor to escalate), the approval availability/rejection/cancellation variants, and tool call aborted.
Only the failing call adds these retained tokens; a rejected escalation does not add command output because the command does not run.
Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
These limits define when the tool is a poor fit or needs special care. They are current package constraints, not a task backlog.
[exit code: N] / [killed by signal: …] shows a wrong pill on session replay and loses that line from the card body, because the parse treats it as the marker it consumes; a display-only known residual.bash tool opts out of timeout-policy budgets — it keeps the executor-owned BASH_TIMEOUT path, per the tool-call timeout-policy Agent Note.job_kill, or rely on owner/service disposal, when work no longer matters.