Ferramenta bash
Permita que Claude solicite comandos de shell que sua aplicação executa em uma sessão bash persistente e retorna como resultados de ferramenta.
A ferramenta bash é uma ferramenta de cliente ("client tool"): Claude não executa comandos por conta própria. Quando você inclui a ferramenta em uma requisição, Claude responde com um bloco tool_use que indica o comando a ser executado. Sua aplicação executa esse comando em uma sessão bash que ela controla e retorna a saída em um bloco tool_result.
Sua aplicação mantém um único processo bash ativo entre as chamadas de ferramenta, de modo que o estado persiste entre os comandos. O diretório de trabalho, as variáveis de ambiente e quaisquer arquivos criados por um comando continuam disponíveis para o próximo comando.
A versão atual da ferramenta é bash_20250124. Para suporte de modelos, cabeçalhos beta e a versão anterior, consulte Versões da ferramenta. Para todas as ferramentas fornecidas pela Anthropic, consulte a Referência de ferramentas.
Casos de uso
- Fluxos de trabalho de desenvolvimento: Execute comandos de build, testes e ferramentas de desenvolvimento
- Automação de sistemas: Execute scripts, gerencie arquivos, automatize tarefas
- Processamento de dados: Processe arquivos, execute scripts de análise, gerencie conjuntos de dados
- Configuração de ambiente: Instale pacotes, configure ambientes
Início rápido
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
tools=[{"type": "bash_20250124", "name": "bash"}],
messages=[
{"role": "user", "content": "List all Python files in the current directory."}
],
)
print(response)Claude responde com stop_reason: "tool_use" e um bloco tool_use que contém o comando para sua aplicação executar:
{
"id": "msg_01XAbCDeFgHiJkLmNoPQrStU",
"model": "claude-opus-5",
"stop_reason": "tool_use",
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'll list all Python files in the current directory for you."
},
{
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lq9",
"name": "bash",
"input": {
"command": "ls *.py"
}
}
]
}Execute input.command na sua sessão bash e envie a saída de volta como um tool_result. Consulte Implementar a ferramenta bash para ver o ciclo completo de ida e volta.
Como funciona
Cada chamada de ferramenta é um ciclo de ida e volta entre Claude e sua aplicação:
- Claude retorna um bloco
tool_usecontendo ocommanda ser executado. - Sua aplicação executa o comando em sua sessão bash.
- Sua aplicação retorna a saída do comando, stdout e stderr juntos, para Claude em um bloco
tool_result. - Claude solicita outro comando na mesma sessão ou responde com texto.
Claude também pode retornar vários blocos tool_use em uma única resposta. Execute-os em ordem na mesma sessão e retorne todos os resultados em uma única mensagem user. Consulte Uso paralelo de ferramentas.
A API é stateless (sem estado). Nada sobre sua sessão de shell trafega entre as requisições, portanto sua aplicação decide quando a sessão começa, por quanto tempo ela vive e quando reiniciá-la. Para o ciclo completo de requisição e resposta, consulte Lidar com chamadas de ferramenta.
Parâmetros
Uma definição da ferramenta bash tem dois campos obrigatórios, type e name, e o name deve ser bash. A ferramenta não tem schema: você não fornece um input_schema, porque o schema está incorporado ao modelo do Claude e não pode ser modificado. A tabela a seguir lista os campos de entrada que Claude define quando chama a ferramenta.
| Parâmetro | Obrigatório | Descrição |
|---|---|---|
command | Sim* | O comando bash a ser executado |
restart | Não | Defina como true para reiniciar a sessão bash |
*Obrigatório, a menos que restart seja usado
Para lidar com restart: true, encerre o processo do shell, inicie um novo e retorne um tool_result que confirme a reinicialização. Uma sessão reiniciada começa limpa: o diretório de trabalho, as variáveis de ambiente e quaisquer processos em execução desaparecem.
Executar um comando:
{
"command": "ls -la *.py"
}Reiniciar a sessão:
{
"restart": true
}Versões da ferramenta
bash_20250124 é a versão atual da ferramenta e não requer cabeçalho beta. Todos os modelos a partir do Claude Sonnet 3.7 (desativado) a aceitam, incluindo todos os modelos Claude atuais.
A versão original bash_20241022 funciona apenas com o modelo Claude Sonnet 3.5 de outubro de 2024 (desativado). Requisições que a utilizam precisam do cabeçalho anthropic-beta: computer-use-2024-10-22, e os SDKs a expõem apenas em seus namespaces beta. Novas integrações devem usar bash_20250124.
Exemplo: Automação em várias etapas
Claude pode encadear comandos entre chamadas de ferramenta para concluir uma tarefa de várias etapas:
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"}A sessão mantém o estado entre os comandos, portanto os arquivos criados na etapa 2 estão disponíveis na etapa 3.
Implementar a ferramenta bash
Claude determina qual comando executar. Sua aplicação é responsável por todo o resto: o processo do shell, o timeout e as verificações de segurança. As etapas a seguir mostram uma implementação mínima.
Criar uma sessão bash persistente
Inicie um único processo bash de longa duração e execute todos os comandos dentro dele. Como um pipe para um processo ativo nunca reporta fim de arquivo, a sessão imprime uma linha sentinela única após cada comando para marcar onde termina a saída daquele comando:
import subprocess import uuid class BashSession: """A bash process that stays alive between commands so state persists.""" def __init__(self): self.process = subprocess.Popen( ["/bin/bash"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, # interleave errors with output, in order start_new_session=True, # own process group: a timeout can kill every child text=True, ) def execute_command(self, command): """Run a command in the session and return its output.""" sentinel = f"__CLAUDE_BASH_DONE_{uuid.uuid4().hex}__" # unique per call self.process.stdin.write(f"{command}\necho {sentinel}\n") self.process.stdin.flush() output = [] for line in self.process.stdout: if sentinel in line: # this command's output is complete break output.append(line) return "".join(output) def restart(self): self.process.kill() self.process.wait() self.__init__() bash_session = BashSession() print(bash_session.execute_command("cd /tmp && pwd")) print(bash_session.execute_command("pwd")) # still /tmp: the session kept its stateA sessão intercala stderr com stdout, de modo que as mensagens de erro aparecem onde ocorreram. O exemplo omite o que uma implementação completa também precisa: um timeout que encerre o shell e todos os processos que ele iniciou quando um comando trava, e então reinicie a sessão. A prática recomendada Usar timeouts de comando mostra uma forma de adicioná-lo.
Processar as chamadas de ferramenta do Claude
Extraia e execute os comandos das respostas do Claude:
tool_results = [] 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) # Um tool_result por bloco tool_use, todos retornados na próxima mensagem do usuário tool_results.append( {"type": "tool_result", "tool_use_id": content.id, "content": result} )Retornar o resultado para Claude
Envie o
tool_resultde volta em uma mensagemuserque continue a mesma conversa. Claude solicita outro comando na mesma sessão ou conclui sua resposta:client = anthropic.Anthropic() response = client.messages.create( model="claude-opus-5", max_tokens=1024, tools=[{"type": "bash_20250124", "name": "bash"}], messages=[ {"role": "user", "content": "List all Python files in the current directory."}, { "role": "assistant", "content": [ { "type": "tool_use", "id": "toolu_01A09q90qw90lq917835lq9", "name": "bash", "input": {"command": "ls *.py"}, } ], }, { "role": "user", "content": [ { "type": "tool_result", "tool_use_id": "toolu_01A09q90qw90lq917835lq9", "content": "analysis.py\nprocess_data.py\n", } ], }, ], ) print(response.content)Repita o ciclo de executar e retornar enquanto
stop_reasonfortool_use. Para o loop completo, consulte Lidando com resultados de ferramentas de cliente.Implementar medidas de segurança
Adicione validação e restrições. Use uma allowlist (lista de permissões) em vez de uma blocklist (lista de bloqueios): uma blocklist deixa passar qualquer comando que não tenha previsto. O exemplo também rejeita operadores de shell que aparecem como palavras separadas:
import shlex ALLOWED_COMMANDS = {"ls", "cat", "echo", "pwd", "grep", "find", "wc", "head", "tail"} SHELL_OPERATORS = {"&&", "||", "|", ";", "&", ">", "<", ">>"} def validate_command(command): # Permitir apenas comandos de uma lista de permissões explícita try: tokens = shlex.split(command) except ValueError: return False, "Could not parse command" if not tokens: return False, "Empty command" executable = tokens[0] if executable not in ALLOWED_COMMANDS: return False, f"Command '{executable}' is not in the allowlist" # Rejeitar operadores de shell escritos como palavras separadas for token in tokens[1:]: if token in SHELL_OPERATORS or token.startswith(("$", "`")): return False, f"Shell operator '{token}' is not allowed" return True, NoneEssa verificação é um alarme para erros óbvios, não uma fronteira de imposição. Ela rejeita o encadeamento com espaços (
&&), pipes e redirecionamentos que os outros exemplos desta página usam. Ela não detecta um operador colado a uma palavra, comocat data.txt|grep x, porque o tokenizador mantémdata.txt|grepdentro de um único token. Decida quais comandos e operadores sua aplicação permite. O controle real é o isolamento: execute toda a sessão dentro de um contêiner ou de uma máquina virtual (consulte Segurança).
Lidar com erros
Quando um comando falha ou a sessão quebra, informe a Claude o que aconteceu. Retorne a mensagem como conteúdo do tool_result e defina is_error como true, o que marca a chamada de ferramenta como falha. Consulte Lidando com erros com is_error.
Se um comando demorar demais para ser executado:
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01A09q90qw90lq917835lq9",
"content": "Error: command did not finish within 30 seconds",
"is_error": true
}
]
}Se um comando não existir:
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01A09q90qw90lq917835lq9",
"content": "bash: nonexistentcommand: command not found",
"is_error": true
}
]
}Se houver problemas de permissão:
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01A09q90qw90lq917835lq9",
"content": "bash: /root/sensitive-file: Permission denied",
"is_error": true
}
]
}Seguir as práticas recomendadas de implementação
Um comando que nunca termina, como um que aguarda entrada, bloqueia a sessão para sempre porque sua linha sentinela nunca chega. Dê a cada comando um prazo. Quando o prazo expirar, pare o shell e tudo o que o comando iniciou e, em seguida, reinicie a sessão:
import concurrent.futures
import os
import signal
def execute_with_timeout(session, command, timeout=30):
"""Run a command in the session, replacing the session if the command hangs."""
with concurrent.futures.ThreadPoolExecutor(max_workers=1) as pool:
future = pool.submit(session.execute_command, command)
try:
return future.result(timeout=timeout)
except concurrent.futures.TimeoutError:
# O grupo é o shell e todos os processos que o comando iniciou
os.killpg(session.process.pid, signal.SIGKILL)
session.restart()
return f"Error: command did not finish within {timeout} seconds"O kill interrompe o comando travado e tudo o que ele iniciou. Retorne a mensagem como um tool_result de erro (consulte Lidar com erros), o que marca a chamada de ferramenta como falha.
Mantenha a sessão bash persistente para preservar as variáveis de ambiente e o diretório de trabalho:
# Comandos executados na mesma sessão mantêm o estado
commands = [
"cd /tmp",
"echo 'Hello' > test.txt",
"cat test.txt", # The session is still in /tmp
]Trunque saídas grandes para evitar problemas com limites de tokens:
def truncate_output(output, max_lines=100):
lines = output.split("\n")
if len(lines) > max_lines:
truncated = "\n".join(lines[:max_lines])
return f"{truncated}\n\n... Output truncated ({len(lines)} total lines) ..."
return outputMantenha uma trilha de auditoria. Encaminhe cada comando por um único wrapper que registre o comando antes de ser executado e a saída depois que ele terminar. Um comando que trava ou quebra a sessão ainda deixa um registro:
import logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(message)s")
def execute_and_log(session, command):
"""Run a command in the session and keep an audit record of it."""
logging.info("command=%r", command)
output = session.execute_command(command)
logging.info("output=%r", output[:200]) # first 200 characters
return outputOs registros vão para stderr por padrão; direcione-os para um arquivo ou para seu pipeline de logging para mantê-los. Inclua tudo o que vincule o registro à requisição na sua aplicação, como o usuário final e o tool_use_id.
Segurança
Além do isolamento, adicione estes controles:
- Valide os comandos antes de executá-los, com uma allowlist em vez de uma blocklist. Consulte Implementar a ferramenta bash.
- Defina limites de recursos no processo do shell (CPU, memória e disco), por exemplo com
ulimit. - Registre cada comando e sua saída para que você possa auditar o que foi executado.
- Remova credenciais e outros segredos da saída antes de retorná-la para Claude.
Preços
A definição da ferramenta bash adiciona os seguintes tokens de entrada à sua requisição. Isso é adicional ao prompt do sistema de uso de ferramentas por modelo, que se aplica sempre que qualquer ferramenta está presente.
| Modelo | Tokens de entrada adicionais |
|---|---|
| Claude Opus 5, Claude Opus 4.8 e Claude Opus 4.7 | 325 tokens |
| Claude Opus 4.6, Claude Sonnet 4.6 e anteriores | 244 tokens |
Tokens adicionais são consumidos por:
- Saídas de comandos (stdout/stderr)
- Mensagens de erro
- Conteúdos de arquivos grandes
Consulte preços de uso de ferramentas para detalhes completos de preços.
Padrões comuns
Fluxos de trabalho de desenvolvimento
- Executar testes:
pytest && coverage report - Fazer build de projetos:
npm install && npm run build - Operações Git:
git status && git add . && git commit -m "message"
Para orientações sobre o uso do git como mecanismo de checkpoint e recuperação em fluxos de trabalho de agentes de longa duração, consulte práticas recomendadas de gerenciamento de estado.
Operações com arquivos
- Processar dados:
wc -l *.csv && ls -lh *.csv - Pesquisar arquivos:
find . -name "*.py" | xargs grep "pattern" - Criar backups:
tar -czf backup.tar.gz ./data
Tarefas de sistema
- Verificar recursos:
df -h && free -m - Gerenciamento de processos:
ps aux | grep python - Configuração de ambiente:
export PATH=$PATH:/new/path && echo $PATH
Limitações
- Sem comandos interativos: A sessão não pode executar
vim,less, prompts de senha ou qualquer comando que aguarde entrada no stdin. - Sem aplicações GUI: A sessão é apenas de linha de comando.
- Escopo da sessão: O estado da sessão bash fica no lado do cliente. Sua aplicação é responsável por manter a sessão de shell entre os turnos.
- Limites de saída: A API não trunca resultados de ferramenta (uma requisição grande demais é rejeitada). Trunque saídas grandes na sua aplicação antes de retorná-las para Claude.
- Sem streaming: A saída só chega a Claude quando sua aplicação retorna o
tool_resultna próxima requisição.
Combinando com outras ferramentas
A ferramenta bash combina bem com a Ferramenta de editor de texto: Claude edita um arquivo com uma ferramenta e solicita o comando que o executa com a outra.
Próximos passos
Visualize e modifique arquivos de texto para depurar, corrigir e melhorar código.
Conecte Claude a ferramentas externas e APIs. Veja onde as ferramentas são executadas, quando Claude as chama e qual ferramenta se adequa à sua tarefa.
Was this page helpful?