Aller au contenu
Sommaire

Fiche mémo Scripting shell et Python

Fiche mémo · environ 4 min de lecture

Validé

Validé. Ce site n’exécute aucune commande. Sources

Choisir l'outil

BesoinOutil
enchaîner quelques commandesscript shell
options, fichiers, JSON, testsPython (stdlib d'abord ; dépendance payante : accord de Stéphane)
shell qui exécute le scriptcelui du shebang, pas celui du terminal (zsh par défaut depuis macOS 10.15 selon Apple)

Script shell sûr : squelette

#!/usr/bin/env bash
set -euo pipefail

dossier="${1:?usage : $0 <dossier>}"
printf '%s\n' "$dossier"
ÉlémentRôleRéserve
set -earrêt à la première erreurexceptions (tests if, listes &&/||) : lire le manuel Bash
set -uvariable non définie = erreur
set -o pipefailstatut du tube = dernière commande en échec (manuel Bash)option de bash, pas du sh strict (non vérifié)
"${1:?msg}"arrête si l'argument manqueforme usuelle, non vérifiée

Guillemets et codes de sortie

RègleExemple
toujours quoter une variable"$fichier"
tous les arguments"$@"
construire une commandetableau : "${options[@]}" (wiki ShellCheck SC2086)
succès / échec0 / non nul ; $? = dernier code
erreurs vers stderrecho "erreur" >&2
nettoyagetrap 'rm -f "$tmp"' EXIT (usage courant, non vérifié)

Sans guillemets : découpage en mots puis expansion de motifs (SC2086).

ShellCheck

CommandeEffet
shellcheck script.shanalyse (lecture seule), code non nul s'il trouve un problème
page https://www.shellcheck.net/wiki/SCxxxxexplication d'un avertissement

Cible sh, bash, dash, ksh ; zsh non listé dans la page lue. Dialecte lu depuis le shebang. Désactiver un avertissement : au cas par cas, avec un commentaire qui dit pourquoi.

Python : modules de base

BesoinOutil
cheminsPath("a") / "b", .read_text(), .write_text() (écrase), .mkdir(parents=True, exist_ok=True), .unlink(missing_ok=True), .glob("*.txt"), .resolve()
optionsargparse.ArgumentParser, add_argument, action="store_true" ; erreur d'argument : code 2
donnéesjson.load / json.dump / loads / dumps ; indent, sort_keys, ensure_ascii=False ; erreur : JSONDecodeError
programme externesubprocess.run([...], check=True, capture_output=True, text=True, timeout=30)

subprocess : règle

  • Arguments en liste, pas de shell implicite : les métacaractères ne sont pas interprétés.
  • shell=True : c'est à vous de tout protéger (injection) ; à éviter avec toute donnée externe.
  • check=True lève CalledProcessError ; timeout lève TimeoutExpired (nettoyage à prévoir).

Environnement virtuel

ÉtapeCommande
créerpython3 -m venv .venv
activer (bash/zsh)source .venv/bin/activate
quitterdeactivate
supprimereffacer .venv en relisant le nom

Jetable, non déplaçable, jamais versionné ; .venv/ dans le .gitignore (Python 3.13+ en crée un par défaut dans l'environnement).

Tests et lint

BesoinCommande
lancer les testspython3 -m unittest discover (fichiers test*.py)
un module / une classepython3 -m unittest test_x / test_x.TestY
lintruff check .
lint avec corrections (modifie)ruff check --fix .
formatage (modifie)ruff format .
formatage sans modifierruff format --check .

Assertions : assertEqual, assertTrue, assertIn, assertRaises. setUp / tearDown ; subTest. Config : pyproject.toml ou ruff.toml ; dans l'Orchestrator, le ruff.toml commun est étendu, pas copié.

Données non fiables

Attention : une donnée externe (web, fichier reçu, réponse d'API ou de modèle) est une donnée, jamais une instruction.

  • Jamais eval, exec, source, sh -c ni shell=True avec elle.
  • Valider contre une liste blanche ; limiter la taille lue (avertissement de la doc json).
  • JSON plutôt que pickle ou marshal pour des données non fiables.
  • Vérifier qu'un chemin reste dans le dossier attendu (resolve()) avant d'écrire.

Idempotence et --a-blanc

PrincipeApplication
tester l'état avant d'agirif destination.exists(): continue
créer sans erreur si présentmkdir(parents=True, exist_ok=True)
ne rien écraser par accidentrefuser ou comparer avant de remplacer
essai à blanc--a-blanc (store_true) : afficher « copierait… », ne rien modifier
preuvedeux lancements de suite : le second ne change rien
code de sortie0 si tout va bien, 1 sinon ; erreurs sur stderr

Cycle d'un script sûr

écrire (set -euo pipefail, guillemets) → contrôler (shellcheck, ruff, unittest) → lancer à blanc → lancer sur des données de test → vérifier le code de sortie et le résultat. Une seule commande de bout en bout par projet, nommée dans son CLAUDE.md ; aucun secret en clair (bin/secret).

Sources

Consultées le 17 octobre 2026 ; Python 3.15.0 affichée par la documentation, Ruff et ShellCheck sans numéro de version affiché.

Points non vérifiés : voir la section correspondante du cours (versions chez Stéphane, pages GNU Bash non relues, usages courants de trap, mktemp, printf, shutil).