Claude Platform Docs
MessagesOutils

Outil bash

Permettez à Claude de demander des commandes shell que votre application exécute dans une session bash persistante et renvoie sous forme de résultats d'outils.

L'outil bash est un outil client : Claude n'exécute pas lui-même les commandes. Lorsque vous incluez l'outil dans une requête, Claude répond avec un bloc tool_use qui indique la commande à exécuter. Votre application exécute cette commande dans une session bash qu'elle possède et renvoie la sortie dans un bloc tool_result.

Votre application maintient un seul processus bash actif d'un appel d'outil à l'autre, de sorte que l'état persiste entre les commandes. Le répertoire de travail, les variables d'environnement et tous les fichiers créés par une commande sont toujours présents pour la commande suivante.

La version actuelle de l'outil est bash_20250124. Pour la prise en charge des modèles, les en-têtes bêta et la version antérieure, consultez Versions de l'outil. Pour tous les outils fournis par Anthropic, consultez la Référence des outils.

Cas d'utilisation

  • Flux de travail de développement : exécuter des commandes de build, des tests et des outils de développement
  • Automatisation système : exécuter des scripts, gérer des fichiers, automatiser des tâches
  • Traitement de données : traiter des fichiers, exécuter des scripts d'analyse, gérer des jeux de données
  • Configuration d'environnement : installer des paquets, configurer des environnements

Démarrage rapide

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-opus-5-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 répond avec stop_reason: "tool_use" et un bloc tool_use qui contient la commande que votre application doit exécuter :

Output
{
  "id": "msg_01XAbCDeFgHiJkLmNoPQrStU",
  "model": "claude-opus-5-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"
      }
    }
  ]
}

Exécutez input.command dans votre session bash et renvoyez la sortie sous forme de tool_result. Consultez Implémenter l'outil bash pour l'aller-retour complet.

Fonctionnement

Chaque appel d'outil correspond à un aller-retour entre Claude et votre application :

  1. Claude renvoie un bloc tool_use contenant la command à exécuter.
  2. Votre application exécute la commande dans sa session bash.
  3. Votre application renvoie la sortie de la commande, stdout et stderr ensemble, à Claude dans un bloc tool_result.
  4. Claude demande une autre commande dans la même session ou répond avec du texte.

Claude peut également renvoyer plusieurs blocs tool_use dans une seule réponse. Exécutez-les dans l'ordre dans la même session et renvoyez tous les résultats dans un seul message user. Consultez Utilisation d'outils en parallèle.

L'API est sans état. Rien concernant votre session shell ne transite entre les requêtes ; c'est donc votre application qui décide quand la session démarre, combien de temps elle vit et quand la redémarrer. Pour le cycle complet de requête et de réponse, consultez Gérer les appels d'outils.

Paramètres

Une définition de l'outil bash comporte deux champs obligatoires, type et name, et name doit être bash. L'outil est sans schéma : vous ne fournissez pas d'input_schema, car le schéma est intégré au modèle de Claude et ne peut pas être modifié. Le tableau suivant répertorie les champs d'entrée que Claude définit lorsqu'il appelle l'outil.

ParamètreObligatoireDescription
commandOui*La commande bash à exécuter
restartNonDéfinir sur true pour redémarrer la session bash

*Obligatoire sauf si restart est utilisé

Pour gérer restart: true, tuez le processus shell, démarrez-en un nouveau et renvoyez un tool_result qui confirme le redémarrage. Une session redémarrée repart de zéro : le répertoire de travail, les variables d'environnement et tous les processus en cours d'exécution ont disparu.

Versions de l'outil

bash_20250124 est la version actuelle de l'outil et ne nécessite aucun en-tête bêta. Tous les modèles à partir de Claude Sonnet 3.7 (retiré) l'acceptent, y compris tous les modèles Claude actuels.

La version originale bash_20241022 ne fonctionne qu'avec le modèle Claude Sonnet 3.5 d'octobre 2024 (retiré). Les requêtes qui l'utilisent nécessitent l'en-tête anthropic-beta: computer-use-2024-10-22, et les SDK ne l'exposent que dans leurs espaces de noms bêta. Les nouvelles intégrations doivent utiliser bash_20250124.

Exemple : automatisation en plusieurs étapes

Claude peut enchaîner des commandes sur plusieurs appels d'outils pour accomplir une tâche en plusieurs étapes :

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 session conserve l'état entre les commandes, de sorte que les fichiers créés à l'étape 2 sont disponibles à l'étape 3.

Implémenter l'outil bash

Claude détermine quelle commande exécuter. Votre application est responsable de tout le reste : le processus shell, le délai d'expiration et les contrôles de sécurité. Les étapes suivantes présentent une implémentation minimale.

  1. Créer une session bash persistante

    Démarrez un processus bash de longue durée et exécutez chaque commande à l'intérieur de celui-ci. Comme un pipe vers un processus actif ne signale jamais de fin de fichier, la session affiche une ligne sentinelle unique après chaque commande pour marquer l'endroit où se termine la sortie de cette commande :

    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 state

    La session entrelace stderr avec stdout, de sorte que les messages d'erreur apparaissent là où ils se sont produits. L'exemple omet ce dont une implémentation complète a également besoin : un délai d'expiration qui tue le shell et tous les processus qu'il a lancés lorsqu'une commande se bloque, puis redémarre la session. La bonne pratique Utiliser des délais d'expiration pour les commandes montre une façon de l'ajouter.

  2. Traiter les appels d'outils de Claude

    Extrayez et exécutez les commandes à partir des réponses de 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 par bloc tool_use, tous renvoyés dans le message utilisateur suivant
            tool_results.append(
                {"type": "tool_result", "tool_use_id": content.id, "content": result}
            )
  3. Renvoyer le résultat à Claude

    Renvoyez le tool_result dans un message user qui poursuit la même conversation. Claude demande une autre commande dans la même session ou termine sa réponse :

    client = anthropic.Anthropic()
    
    response = client.messages.create(
        model="claude-opus-5-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)

    Répétez le cycle d'exécution et de renvoi tant que stop_reason vaut tool_use. Pour la boucle complète, consultez Gérer les résultats des outils clients.

  4. Mettre en place des mesures de sécurité

    Ajoutez des validations et des restrictions. Utilisez une « allowlist » (liste d'autorisation) plutôt qu'une « blocklist » (liste de blocage) : une liste de blocage laisse passer toute commande qu'elle n'a pas anticipée. L'exemple rejette également les opérateurs shell qui apparaissent sous forme de mots distincts :

    import shlex
    
    ALLOWED_COMMANDS = {"ls", "cat", "echo", "pwd", "grep", "find", "wc", "head", "tail"}
    SHELL_OPERATORS = {"&&", "||", "|", ";", "&", ">", "<", ">>"}
    
    
    def validate_command(command):
        # Autoriser uniquement les commandes d'une liste d'autorisation explicite
        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"
    
        # Rejeter les opérateurs shell écrits comme des mots séparés
        for token in tokens[1:]:
            if token in SHELL_OPERATORS or token.startswith(("$", "`")):
                return False, f"Shell operator '{token}' is not allowed"
    
        return True, None

    Cette vérification est un garde-fou contre les erreurs évidentes, pas une frontière de contrôle. Elle rejette l'enchaînement avec espaces (&&), les pipes et les redirections que les autres exemples de cette page utilisent. Elle ne détecte pas un opérateur collé à un mot, comme cat data.txt|grep x, car le tokenizer conserve data.txt|grep dans un seul jeton. Décidez quelles commandes et quels opérateurs votre application autorise. Le véritable contrôle est l'isolation : exécutez toute la session dans un conteneur ou une machine virtuelle (consultez Sécurité).

Gérer les erreurs

Lorsqu'une commande échoue ou que la session se rompt, indiquez à Claude ce qui s'est passé. Renvoyez le message comme contenu du tool_result et définissez is_error sur true, ce qui marque l'appel d'outil comme ayant échoué. Consultez Gestion des erreurs avec is_error.

Suivre les bonnes pratiques d'implémentation

Sécurité

Au-delà de l'isolation, ajoutez ces contrôles :

  • Validez les commandes avant de les exécuter, avec une liste d'autorisation plutôt qu'une liste de blocage. Consultez Implémenter l'outil bash.
  • Définissez des limites de ressources sur le processus shell (CPU, mémoire et disque), par exemple avec ulimit.
  • Journalisez chaque commande et sa sortie afin de pouvoir auditer ce qui a été exécuté.
  • Masquez les identifiants et autres secrets dans la sortie avant de la renvoyer à Claude.

Tarification

La définition de l'outil bash ajoute les tokens d'entrée suivants à votre requête. Cela s'ajoute à l'invite système d'utilisation d'outils propre à chaque modèle, qui s'applique dès qu'un outil est présent.

ModèleTokens d'entrée supplémentaires
Claude Opus 5, Claude Opus 4.8 et Claude Opus 4.7325 tokens
Claude Opus 4.6, Claude Sonnet 4.6 et versions antérieures244 tokens

Des tokens supplémentaires sont consommés par :

  • Les sorties de commandes (stdout/stderr)
  • Les messages d'erreur
  • Les contenus de fichiers volumineux

Consultez la tarification de l'utilisation d'outils pour tous les détails de tarification.

Modèles courants

Flux de travail de développement

  • Exécuter des tests : pytest && coverage report
  • Compiler des projets : npm install && npm run build
  • Opérations Git : git status && git add . && git commit -m "message"

Pour des conseils sur l'utilisation de git comme mécanisme de point de contrôle et de récupération dans les flux de travail d'agents de longue durée, consultez les bonnes pratiques de gestion d'état.

Opérations sur les fichiers

  • Traiter des données : wc -l *.csv && ls -lh *.csv
  • Rechercher des fichiers : find . -name "*.py" | xargs grep "pattern"
  • Créer des sauvegardes : tar -czf backup.tar.gz ./data

Tâches système

  • Vérifier les ressources : df -h && free -m
  • Gestion des processus : ps aux | grep python
  • Configuration de l'environnement : export PATH=$PATH:/new/path && echo $PATH

Limitations

  • Pas de commandes interactives : la session ne peut pas exécuter vim, less, des invites de mot de passe ni aucune commande qui attend une saisie sur stdin.
  • Pas d'applications graphiques : la session est uniquement en ligne de commande.
  • Portée de la session : l'état de la session bash est côté client. Votre application est responsable du maintien de la session shell entre les tours.
  • Limites de sortie : l'API ne tronque pas les résultats d'outils (une requête trop volumineuse est rejetée). Tronquez les sorties volumineuses dans votre application avant de les renvoyer à Claude.
  • Pas de streaming : la sortie ne parvient à Claude que lorsque votre application renvoie le tool_result dans la requête suivante.

Combinaison avec d'autres outils

L'outil bash se combine bien avec l'outil d'édition de texte : Claude modifie un fichier avec un outil et demande la commande qui l'exécute avec l'autre.

Étapes suivantes

Affichez et modifiez des fichiers texte pour déboguer, corriger et améliorer du code.

Connectez Claude à des outils et API externes. Découvrez où les outils s'exécutent, quand Claude les appelle et quel outil convient à votre tâche.

Was this page helpful?