Aller au contenu principal

Frontières des programmes en ligne de commande

Un programme en ligne de commande communique par arguments, variables d'environnement, flux standard, fichiers et état de sortie. Traitez chacun comme une interface publique dont d'autres programmes peuvent dépendre.

Flux

  • stdin transporte les données d'entrée.
  • stdout transporte le résultat demandé.
  • stderr transporte diagnostics et progression sans corrompre un pipeline.

input() lit une ligne de stdin après avoir éventuellement affiché une invite. Il convient aux outils interactifs, pas aux pipelines de données. Pour une entrée en flux, parcourez sys.stdin ; employez print pour la sortie utilisateur et logging pour les événements opérationnels.

import sys

for line in sys.stdin:
sys.stdout.write(line.upper())

Une sortie destinée aux machines doit rester dépourvue de titres, couleurs et journaux accessoires. Proposez un mode structuré séparé, comme JSON, si des scripts la consomment.

Arguments et configuration

Utilisez argparse plutôt que d'indexer manuellement sys.argv :

import argparse
from pathlib import Path

parser = argparse.ArgumentParser()
parser.add_argument("input", type=Path)
parser.add_argument("--format", choices=("text", "json"), default="text")
args = parser.parse_args()

Les arguments sont explicites et visibles dans les listes de processus et l'historique du shell. Ils ne conviennent pas aux secrets. Les variables d'environnement servent à la configuration héritée du déploiement, mais sont des chaînes, peuvent aussi fuiter lors d'une inspection ou d'un diagnostic et ne constituent pas un coffre-fort.

import os

endpoint = os.environ.get("APP_ENDPOINT", "https://example.invalid")

Analysez et validez la configuration une fois, près du démarrage. Distinguez une variable absente d'une valeur vide si le domaine l'exige. Ne modifiez pas l'environnement global du processus au fond du code de bibliothèque.

État de sortie

Renvoyez zéro en cas de réussite et un état non nul documenté en cas d'échec. Une fonction main rend ce contrat testable :

def main() -> int:
...
return 0

if __name__ == "__main__":
raise SystemExit(main())

Les exceptions sont un mécanisme interne ; l'état de sortie et stderr forment le contrat externe de la CLI. Ne capturez à la frontière que les exceptions que l'outil peut traduire en diagnostic utile et état stable. Préservez assez de contexte pour déboguer sans afficher secrets ni charges sensibles complètes.

Sources

Explorer les liens

Cette note n’a pas encore de liens vers d’autres notes.

Sur les mêmes sujets (47)

Ouvrir le réseau