Bash ou Python, pour l'automatisation ?

En tant que développeur, j'ai eu l'occasion de beaucoup scripter, pour mes pipelines Gitlab. À un moment donné, j'ai atteint les limites de Bash, et j'ai dû opter pour Python, dans certains cas ...
Bash ou Python, pour l'automatisation ?

Cette semaine, j’ai commencé à reprendre en main un vieux support pour une formation Linux et Bash. Un des points clés de cette formation porte sur les bonnes pratiques de Bash et quelques limites que j’avais rencontrées.

La base sous Linux

Bash est « le » langage avec lequel on rédige le plus de scripts sous Linux : il est disponible en standard sur la plupart des distributions courantes (basées Red Hat, SUSE et Debian) et sur Mac OS, car il est POSIX (le standard pour les logiciels Unix, dont héritent Linux et l’OS à la pomme).

Le gros atout de Bash est de facto de permettre de manipuler directement n’importe quel programme accessible en ligne de commande, et de chaîner ces commandes entre elles via les outils de manipulation de flux (« | », « > », etc.).

Par exemple :

~$ tail -f /var/log/some-soft.log | grep "error"

permet de récupérer en temps réel tout les messages de log contenant « error » pour notre programme « some-soft ».

Quand on se heurte aux limites

Pour avoir exploré à fond le scripting avec Bash, je peux vous dire qu’il n’est pas non plus universel.

  • Bash permet par exemple la manipulation de chaînes de caractères (avec ${} et des expansions), mais la syntaxe n’est pas très maintenable et est difficile à suivre, lorsqu’on en fait beaucoup.
  • De même avec sed et awk : très puissants, ils nécessitent un « bash-elor » dédié dès qu’on manipule des regex complexes.
  • Enfin, j’ai vite plafonné sur la longueur des scripts. À ce moment-là, on commence à le découper en modules, qu’il faut importer dans notre script principal, et cela devient rapidement un casse-tête chinois en Bash.

Python à la rescousse

De par mon expertise, je me suis alors tourné vers Python. Ce langage interprété est très flexible, versatile, et facile à prendre en main. Il ne permet pas ce que permet Bash avec autant d’aisance, mais pour ce qui est du développement modulaire, la manipulation de chaînes de caractères ou de fichiers, il est excellent.

L’exemple du versioning

Pour vous donner un exemple concret, j’ai eu à manipuler des versions de packages utilisant un SemVer customisé.

Si vous avez lu mon article R2PL, vous en avez déjà eu un petit aperçu : SemVer permet de facilement distinguer les changements majeurs (cassants par rapport au comportement habituel), mineurs (évolutions sans rupture) et patchs (correction de bugs et failles de sécurité).

Dans notre usage « custom » nous avons ajouté deux subtilités :

  • Les Release Candidates sont des versions « .rcX » où X est le numéro de candidate.
  • Un autre cas que j’ai vu passer (assez similaire dans la logique) étaient des versions « .devY » où Y était un numéro de commit sur le repo git.

J’avais alors besoin d’un script, exécuté via pipelines de release, qui permette d’incrémenter suivant les cas de figure (sur quelle branche je me trouve, selon le tag, etc.) la version majeure, ou bien mineure, ou bien de patch … ou bien de Release Candidate. Le cas des versions de dev (avec numéro de commit) est d’ailleurs particulièrement intéressant, pour notre exemple.

En Bash, il est assez facile d’utiliser git pour récupérer un numéro de commit, ou le nom d’une branche, mais avec Python, j’ai juste eu besoin d’une petite classe pour gérer de façon intuitive les montées de version de mon package. Et parlant de package, après avoir appelé Python pour calculer sa bonne version, je repassais en Bash pour générer un paquet RPM propre (ça donne une piste sur mon environnement de dev 😜).

S’y retrouver en eaux troubles

Alors bien sûr, il existe des outils autant en Bash qu’en Python qui permettent de faire le travail de l’un avec l’autre. Par exemple, on a maintenant jq qui facilite énormément la manipulation de json en Bash. Les fichiers de configuration de Gitlab CI et Github Action viennent également impacter les choix, avec leurs choix et leur syntaxe (par exemple, ils facilitent l’enchaînement de commandes Bash dans un environnement isolé).

Mais par expérience, il vaut mieux que chacun reste dans son domaine, et nos pipelines seront bien gardés 😉

  • Bash pour automatiser des actions en ligne de commande, et
  • Python pour des scripts plus lourds et les manipulations complexes sur les données.

Write a comment
No comments yet.