====== Bonnes pratiques en shellscript / bash ====== ===== Shebang! ===== La première ligne d'un script shell contient toujours ce qu'on appelle le ''shebang'', qui est utile pour indiquer au système qu'il s'agit d'un script shell (ou php, ou python, ou perl, etc). Dans le cas de bash, le shebang se présente sous cette forme : #!/bin/bash Parfois on voit aussi des scripts shell commencer par ''#!/bin/sh''. La bonne pratique veut que l'on n'utilise cette forme (avec ''/bin/sh'' et non ''/bin/bash'') que pour les scripts d'init, car le shell ''/bin/sh'' n'est pas nécessairement bash. Dans le cas de Debian notamment, il s'agit de dash, un shell allégé spécifiquement pour lancer ces scripts d'initialisation. Si vous comptez utiliser des spécificités bash, donc, préférez ''#!/bin/bash''. ===== Sous-commandes (subcommands) ===== Il existe en shellscript deux possibilités pour exécuter des sous-commandes : `avec des backticks` ou alors $(avec $parenthèses) La première solution ne devrait être utilisée que dans les cas où cela s'avère absolument nécessaire (un script écrit pour de très vieux shells Bourne non-POSIX). Dans tous les cas il faut préférer la forme $(). Référence : http://mywiki.wooledge.org/BashFAQ/082 ===== Largeur ===== Pour des raisons historiques (largeur des terminaux de l'époque), la convention veut que les lignes d'un script ne dépassent pas les 88 caractères. Si toutefois vous deviez écrire des lignes plus longues que ça, vous pouvez les étaler sur plusieurs lignes en mettant ''\ '' (barre oblique inversée + espace) avant chaque retour à la ligne. Il y a aussi une autre raison à cela : les lignes trop longues sont moins lisibles, l'œil devant faire plus d'efforts pour retrouver la ligne suivante. ===== Indentation ===== Attention, troll incoming ! Il n'y a pas de convention à ce jour. Généralement, on voit trois variantes (si vous en connaissez d'autres, n'hésitez pas) : * 2 espaces * 4 espaces * 1 tabulation ===== Noms des variables ===== Encore un troll... On peut écrire le nom des variables en ''$MAJUSCULE'' ou en ''$minuscule'' (ou en ''$mIXeD'', mais c'est plus moche qu'autre chose, ça rend le tout illisible -- autant écrire du brainfuck). Une convention veut que les noms des variables soient écrits en minuscules, avec un préfixe pour éviter la collision avec des noms réservés (comme par exemple ''$PATH'', cf. la documentation de bash pour une liste complète). Cela pourrait ressembler à ça : ''$my_email'', ''$my_source_path'', etc. ===== Fonctions ===== Déclarer une fonction sans utiliser le mot-clef ''function'', c'est obsolète. ===== Toujours utiliser des guillemets ===== Parfois un exemple vaut mille mots : my_sentence="Cachez ces bits que je ne saurais voir !" echo $my_sentence Cachez ces bits que je ne saurais voir ! echo "$my_sentence" Cachez ces bits que je ne saurais voir ! ===== eval ===== Ne jamais utiliser ''eval'', à moins de savoir ce que l'on fait ! ''eval'' fait que du code est exécuté deux fois. Si par exemple une variable contient du code, eh bien il sera exécuté. Cela est potentiellement une faille de sécurité béante, si on ne fait pas attention à ce qu'on fait. Plus de détails ici https://mywiki.wooledge.org/BashFAQ/048 ===== Fail early ===== C'est une expression à prendre au pied de la lettre : si une erreur doit avoir lieu, cela doit se passer le plus tôt possible. Par conséquent, une bonne pratique est, avant même d'écrire le code que l'on veut que notre script exécute, de vérifier si toutes les commandes qui y seront utilisées sont bien existantes : my_needed_commands="sed awk lsof who" missing_counter=0 for needed_command in $my_needed_commands; do if ! hash "$needed_command" >/dev/null 2>&1; then printf "Command not found in PATH: %s\n" "$needed_command" >&2 ((missing_counter++)) fi done if ((missing_counter > 0)); then printf "At least %d commands are missing in PATH, aborting\n" "$missing_counter" >&2 exit 1 fi On pourrait même pousser l'idée plus loin en testant les options des commandes utilisées (je pense par exemple à awk, pour qui il existe plein d'implémentation différentes). ===== Code de sortie ===== Toujours sortir du script avec un bon code de sortie ("exit status") et éviter à tout prix de toujours terminer avec un code 0. Si ce n'est pas fait comme il faut, le script peut potentiellement produire des erreurs et continuer tout de même. Cela devient encore pire si le script est utilisé dans une suite de plusieurs commandes. ===== Liens ===== http://mywiki.wooledge.org/BashGuide/Practices (la bible bash, à avoir absolument sur votre table de chevet !) http://wiki.bash-hackers.org/scripting/style {{tag>bash shellscript bestpractices sysadmin}}