Questa funzionalità è idonea per la Zero Data Retention (ZDR). Quando la tua organizzazione dispone di un accordo ZDR, i dati inviati tramite questa funzionalità non vengono conservati dopo che la risposta dell'API è stata restituita.
Lo strumento bash è uno strumento client: Claude non esegue i comandi da solo. Quando includi lo strumento in una richiesta, Claude risponde con un blocco tool_use che indica il comando da eseguire. La tua applicazione esegue quel comando in una sessione bash di sua proprietà e restituisce l'output in un blocco tool_result.
La tua applicazione mantiene attivo un unico processo bash tra le chiamate allo strumento, quindi lo stato persiste tra i comandi. La directory di lavoro, le variabili d'ambiente e qualsiasi file creato da un comando sono ancora presenti per il comando successivo.
La versione corrente dello strumento è bash_20250124. Per il supporto dei modelli, gli header beta e la versione precedente, consulta Versioni dello strumento. Per tutti gli strumenti forniti da Anthropic, consulta il Riferimento degli strumenti.
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
tools=[{"type": "bash_20250124", "name": "bash"}],
messages=[
{"role": "user", "content": "List all Python files in the current directory."}
],
)
print(response)Claude risponde con stop_reason: "tool_use" e un blocco tool_use che contiene il comando che la tua applicazione deve eseguire:
{
"id": "msg_01XAbCDeFgHiJkLmNoPQrStU",
"model": "claude-opus-4-8",
"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"
}
}
]
}Esegui input.command nella tua sessione bash e invia l'output come tool_result. Consulta Implementare lo strumento bash per il ciclo completo.
Ogni chiamata allo strumento è un ciclo di andata e ritorno tra Claude e la tua applicazione:
tool_use contenente il command da eseguire.tool_result.Claude può anche restituire più blocchi tool_use in una singola risposta. Eseguili in ordine nella stessa sessione e restituisci tutti i risultati in un unico messaggio user. Consulta Uso degli strumenti in parallelo.
L'API è stateless. Nulla della tua sessione shell viaggia tra le richieste, quindi la tua applicazione decide quando la sessione inizia, quanto dura e quando riavviarla. Per il ciclo completo di richiesta e risposta, consulta Gestire le chiamate agli strumenti.
Una definizione dello strumento bash ha due campi obbligatori, type e name, e il name deve essere bash. Lo strumento è privo di schema: non fornisci un input_schema, perché lo schema è integrato nel modello di Claude e non può essere modificato. La tabella seguente elenca i campi di input che Claude imposta quando chiama lo strumento.
| Parametro | Obbligatorio | Descrizione |
|---|---|---|
command | Sì* | Il comando bash da eseguire |
restart | No | Imposta su true per riavviare la sessione bash |
*Obbligatorio a meno che non si usi restart
Per gestire restart: true, termina il processo della shell, avviane uno nuovo e restituisci un tool_result che conferma il riavvio. Una sessione riavviata parte pulita: la directory di lavoro, le variabili d'ambiente e qualsiasi processo in esecuzione sono scomparsi.
bash_20250124 è la versione corrente dello strumento e non richiede alcun header beta. Ogni modello a partire da Claude Sonnet 3.7 (ritirato) lo accetta, inclusi tutti i modelli Claude attuali.
La versione originale bash_20241022 fa parte della beta di computer use, e la release di Claude Sonnet 3.5 di ottobre 2024 (ritirata) è l'unico modello che la accetta. Le richieste che la utilizzano necessitano dell'header anthropic-beta: computer-use-2024-10-22, e gli SDK la espongono solo nei loro namespace beta. Le nuove integrazioni dovrebbero usare bash_20250124.
Claude può concatenare comandi tra le chiamate allo strumento per completare un'attività multi-step:
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"}La sessione mantiene lo stato tra i comandi, quindi i file creati nel passaggio 2 sono disponibili nel passaggio 3.
Claude determina quale comando eseguire. La tua applicazione possiede tutto il resto: il processo della shell, il timeout e i controlli di sicurezza. I passaggi seguenti mostrano un'implementazione minima.
Crea una sessione bash persistente
Avvia un unico processo bash a lunga durata ed esegui ogni comando al suo interno. Poiché una pipe verso un processo attivo non segnala mai la fine del file, la sessione stampa una riga sentinella univoca dopo ogni comando per indicare dove termina l'output di quel 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 stateLa sessione intercala stderr con stdout, così i messaggi di errore compaiono dove si sono verificati. L'esempio tralascia ciò di cui un'implementazione completa ha anche bisogno: un timeout che termina la shell e ogni processo che ha avviato quando un comando si blocca, per poi riavviare la sessione. La best practice Usa timeout per i comandi mostra un modo per aggiungerlo.
Elabora le chiamate allo strumento di Claude
Estrai ed esegui i comandi dalle risposte di 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)
# Un tool_result per ogni blocco tool_use, tutti restituiti nel messaggio utente successivo
tool_results.append(
{"type": "tool_result", "tool_use_id": content.id, "content": result}
)Restituisci il risultato a Claude
Invia il tool_result in un messaggio user che continua la stessa conversazione. Claude richiede un altro comando nella stessa sessione oppure completa la sua risposta:
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-4-8",
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)Ripeti il ciclo di esecuzione e restituzione finché stop_reason è tool_use. Per il ciclo completo, consulta Gestione dei risultati dagli strumenti client.
Implementa misure di sicurezza
Aggiungi validazione e restrizioni. Usa una allowlist anziché una blocklist: una blocklist non intercetta i comandi che non ha previsto. L'esempio rifiuta anche gli operatori di shell che compaiono come parole separate:
import shlex
ALLOWED_COMMANDS = {"ls", "cat", "echo", "pwd", "grep", "find", "wc", "head", "tail"}
SHELL_OPERATORS = {"&&", "||", "|", ";", "&", ">", "<", ">>"}
def validate_command(command):
# Consenti solo i comandi presenti in una allowlist esplicita
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"
# Rifiuta gli operatori di shell scritti come parole separate
for token in tokens[1:]:
if token in SHELL_OPERATORS or token.startswith(("$", "`")):
return False, f"Shell operator '{token}' is not allowed"
return True, NoneQuesto controllo è un campanello d'allarme per errori evidenti, non un confine di sicurezza. Rifiuta il concatenamento con spazi (&&), le pipe e la redirezione che gli altri esempi di questa pagina utilizzano. Non intercetta un operatore attaccato a una parola, come cat data.txt|grep x, perché il tokenizer mantiene data.txt|grep all'interno di un unico token. Decidi quali comandi e operatori la tua applicazione consente. Il vero controllo è l'isolamento: esegui l'intera sessione all'interno di un container o di una macchina virtuale (consulta Sicurezza).
Quando un comando fallisce o la sessione si interrompe, comunica a Claude cosa è successo. Restituisci il messaggio come contenuto del tool_result e imposta is_error su true, il che contrassegna la chiamata allo strumento come fallita. Consulta Gestione degli errori con is_error.
La tua applicazione esegue qualsiasi comando Claude richieda. Esegui la sessione in un ambiente isolato, come un container o una macchina virtuale, con l'utente con i privilegi minimi in grado di svolgere il lavoro. Tratta ogni comando come input non attendibile.
Oltre all'isolamento, aggiungi questi controlli:
ulimit.La definizione dello strumento bash aggiunge i seguenti token di input alla tua richiesta. Questo si aggiunge al prompt di sistema per l'uso degli strumenti specifico per modello che si applica ogni volta che è presente uno strumento.
| Modello | Token di input aggiuntivi |
|---|---|
| Claude Opus 4.7 e Claude Opus 4.8 | 325 token |
| Claude Opus 4.6, Claude Sonnet 4.6 e precedenti | 244 token |
Token aggiuntivi vengono consumati da:
Consulta i prezzi dell'uso degli strumenti per i dettagli completi sui prezzi.
pytest && coverage reportnpm install && npm run buildgit status && git add . && git commit -m "message"Per indicazioni sull'uso di git come meccanismo di checkpoint e ripristino nei flussi di lavoro di agenti a lunga esecuzione, consulta le best practice per la gestione dello stato.
wc -l *.csv && ls -lh *.csvfind . -name "*.py" | xargs grep "pattern"tar -czf backup.tar.gz ./datadf -h && free -mps aux | grep pythonexport PATH=$PATH:/new/path && echo $PATHvim, less, prompt di password o qualsiasi comando che attende input su stdin.tool_result nella richiesta successiva.Lo strumento bash si abbina bene allo strumento Text editor: Claude modifica un file con uno strumento e richiede il comando che lo esegue con l'altro.
Se stai usando anche lo strumento Code execution, Claude ha accesso a due ambienti di esecuzione separati: la tua sessione bash locale e il container sandbox di Anthropic. Lo stato non è condiviso tra di essi. Consulta Usare code execution con altri strumenti di esecuzione per indicazioni su come istruire Claude a distinguere tra gli ambienti.
Visualizza e modifica file di testo per eseguire il debug, correggere e migliorare il codice.
Connetti Claude a strumenti e API esterni. Scopri dove vengono eseguiti gli strumenti, quando Claude li chiama e quale strumento è adatto alla tua attività.
Was this page helpful?