Aller au contenu principal

Développer des scripts shell

Le développement de scripts shell, également connu sous le nom de scripting shell, consiste à écrire des programmes ou des scripts dans un langage de script de shell pour automatiser des tâches ou effectuer des opérations sur un système d'exploitation Linux.

Le scripting Shell pour les DevOps

Ceci n'est que l'avis de l'auteur : Il est important pour un consultant DevOps d'apprendre le scripting shell !

Pourquoi ? : Car vous le rencontrerez très souvent. Il est encore couramment utilisé.

Vous serez amené à :

  • Porter des scripts bash dans un langage plus évolué, du python par exemple
  • À devoir écrire ou modifier des scripts
  • À écrire quelques scripts bash pour résoudre des problèmes ou des petites taches d'administration.

Si j'ai trois conseils à vous donner :

  • Apprenez à écrire des scripts simples pour apprendre au minimum à lire et comprendre du code existant
  • Apprenez un autre langage, le python par exemple, qui est un langage structuré qui possède une large librairie et une communauté importante. Les résultats seront plus idempotents que ceux d'un script shell.
  • Si je devais démarrer un nouveau projet, je ne le ferais pas avec du bash !

Qu'est-ce que le Shell Bash

Le Shell Bash (Bourne-Again Shell), souvent simplement appelé Bash, est un interpréteur de commandes largement utilisé dans les systèmes Linux. Il offre un moyen puissant d'interagir avec votre système d'exploitation via une interface en ligne de commande.

Installation du shell Bash

La première étape pour travailler avec le Shell Bash est de s'assurer qu'il est installé sur votre système. Dans la plupart des distributions Linux, il est préinstallé. Pour vérifier si Bash est déjà installé sur votre système, ouvrez un terminal et saisissez la commande suivante :

bash --version
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2020 Free Software Foundation, Inc.
Licence GPLv3+ : GNU GPL version 3 ou ultérieure <http://gnu.org/licenses/gpl.html>

Ceci est un logiciel libre ; vous être libre de le modifier et de le redistribuer.
AUCUNE GARANTIE n'est fournie, dans les limites permises par la loi.

Si vous obtenez une erreur alors, du genre command not found: bash , il faut l'installer :

sudo apt install bash

Syntaxe et variables des scripts Bash

Pour bien comprendre le développement de scripts shell Bash, il est essentiel de maîtriser la syntaxe de base du langage et de comprendre comment utiliser les variables.

Syntaxe

Les scripts Bash sont essentiellement des fichiers texte contenant une séquence d'instructions Bash. Voici quelques éléments de base de la syntaxe des scripts Bash :

  • Commentaires : Vous pouvez ajouter des commentaires dans vos scripts en utilisant le caractère #. Tout ce qui suit un # sur une ligne est considéré comme un commentaire et est ignoré lors de l'exécution du script.

    Exemple de commentaire :

    # Ceci est un commentaire
    
  • Commandes : Les commandes Bash sont exécutées en tant que lignes de texte dans le script. Chaque commande est séparée par un retour à la ligne. Par exemple, pour afficher du texte à l'écran, vous pouvez utiliser la commande echo !

    Exemple de commande :

    echo "Bonjour, monde !"
    
  • Séparateurs : Le point-virgule (;) est utilisé pour séparer plusieurs commandes sur une seule ligne, mais cela n'est pas couramment pratiqué sauf dans des situations spécifiques.

  • Structure d'un script : Un script Bash commence généralement par une ligne appelée "shebang" (#!) qui indique le chemin de l'interpréteur à utiliser pour exécuter le script. Par exemple, pour utiliser Bash, la première ligne du script est généralement :

    #!/usr/bin/env bash
    
  • Indentation : Bien que l'indentation ne soit pas aussi cruciale en Bash que dans certains autres langages, il est recommandé d'indenter votre code afin d'en améliorer la lisibilité.

Les variables en Bash

Les variables sont essentielles pour stocker des données dans un script Bash. Voici comment déclarer, assigner et utiliser des variables en Bash.

Les noms de variables sont sensibles à la casse, ce qui signifie que nom et Nom sont des variables différentes. Je vous recommande d'utiliser des noms de variables en minuscules pour éviter toute confusion avec les variables d'environnement système, qui sont généralement en majuscules.

Typer les variables, déclarer des constantes

Contrairement à de nombreux autres langages de programmation, le Bash ne type pas ses variable. Mais Il peut être intéressant de typer une variable. Pour ce faire, il faut utiliser des commandes internes à bash qui permettent de déclarer une variable typée. Pour cela on fait appel aux fonctions declare ou typeset (ce sont des synonymes)

declare [OPTION] nom=valeur

Les principales options :

  • -r : Créé une variable en lecture seule, une constante
  • -i : Un entier
  • -a : Un tableau
  • -f : Une fonction
  • -x : Ceci déclare la disponibilité d'une variable pour une exportation en dehors de l'environnement du script lui-même.
  • -x var=value : Assigne une valeur à une variable lors de sa déclaration.

Exemple :

declare -i x=35*2

Déclaration de variables

Vous pouvez déclarer une variable en utilisant le signe égal (=) sans espaces autour du signe, suivi du nom de la variable.

Exemple de déclaration de variable :

nom="John"
age=30

Utilisation de variables

Vous pouvez accéder aux valeurs stockées dans une variable en plaçant le nom de la variable précédé du caractère $ et utilisant la fonction echo.

Exemple d'utilisation de variables :

echo "Mon nom est $nom et j'ai $age ans."

Les variables d'environnement

Les variables d'environnement sont des variables système utilisées par le système d'exploitation et les applications pour stocker des informations importantes sur l'environnement de travail du système. Elles sont utilisées pour influencer le comportement global du système, des programmes et des processus. Les variables d'environnement peuvent contenir divers types d'informations, telles que des chemins de recherche, des paramètres de configuration, des informations de localisation, des informations d'identification, etc.

Les variables d'environnement sont disponibles pour tous les processus et applications en cours d'exécution sur le système. Elles sont généralement utilisées pour partager des informations importantes entre différents programmes.

Vous pouvez définir, modifier et supprimer des variables d'environnement en utilisant des commandes spécifiques dans le Shell. Par exemple, en Shell Bash, vous pouvez utiliser la commande export pour définir une variable d'environnement.

#!/usr/bin/env bash

# Accéder à la variable d'environnement USER
export MA_VARIABLE=toto

echo "L'utilisateur actuel est $MA_VARIABLE."

Pour distinguer les variables d'environnements des autres variables, on les mets en majuscule.

Les variables d'environnement courantes

Il existe de nombreuses variables d'environnement couramment utilisées. En voici quelques exemples :

  • PATH : Contient une liste de répertoires où le système recherche les exécutables des commandes.
  • HOME : Le répertoire personnel de l'utilisateur.
  • USER : Le nom de l'utilisateur actuel.
  • LANG : La configuration de la langue et de la localisation.
  • SHELL : Le chemin du Shell par défaut de l'utilisateur.
  • PWD : Le répertoire actuel

Les variables intégrées

En Shell Bash, les "builtin variables" (variables intégrées) font référence à un ensemble de variables spéciales qui sont automatiquement définies par l'interpréteur de commandes Bash. Ces variables sont largement utilisées dans les scripts pour accéder à des informations importantes. Voici quelques-unes des variables intégrées les plus couramment utilisées :

  • $? : Contient le code de retour de la dernière commande exécutée. Une valeur de 0 indique que la commande s'est exécutée avec succès, tandis qu'une valeur différente de 0 indique une erreur.
  • $$ : Contient le PID (Process ID) du shell en cours d'exécution. Cette valeur est unique pour chaque instance du shell.
  • $0, $1, $2, ... : Ces variables sont utilisées pour accéder aux arguments de ligne de commande passés à un script ou à une commande. $0 représente le nom du script lui-même, tandis que $1, $2, etc., représentent les arguments individuels.
  • $# : Contient le nombre total d'arguments de ligne de commande passés à un script ou à une commande.
  • $@ : Contient tous les arguments de ligne de commande passés à un script ou à une commande sous forme de liste.
  • $* : Contient tous les arguments de ligne de commande passés à un script ou à une commande sous forme d'une seule chaîne de caractères.

Lire l'entrée de l'utilisateur

Pour demander à utilisateur de saisir une variable, on utilise la commande read :

#!/usr/bin/env bash

# Demander à l'utilisateur son nom
echo "Quel est votre nom ?"
read nom_utilisateur

# Afficher un message de bienvenue
echo "Bienvenue, $nom_utilisateur !"

Les Opérations de contrôle

Pour créer des scripts Bash puissants et flexibles, vous devez comprendre comment utiliser les opérations de contrôle. Cela inclut les structures conditionnelles telles que if, else, elif et les boucles comme for et while.

Structures conditionnelles

Les structures conditionnelles vous permettent d'exécuter des blocs de code en fonction de conditions spécifiques. Voici comment elles fonctionnent en Bash :

Structure if... then... else ... fi

La structure if permet d'exécuter un bloc de code si une condition est vraie (true). Voici un exemple :

#!/usr/bin/env bash

age=25

if [[ $age -lt 18 ]] then
  echo "Vous êtes mineur."
else
  echo "Vous êtes majeur."
fi

Dans cet exemple, le script vérifie si la variable age est inférieure à 18. Si c'est le cas, il affiche "Vous êtes mineur." Sinon, il affiche "Vous êtes majeur."

L'utilisation de elif permet de gérer plusieurs conditions de manière séquentielle. Voici un exemple :

#!/usr/bin/env bash

note=75

if [[ $note -ge 90 ]] then
  echo "A"
elif [[ $note -ge 80 ]] then
  echo "B"
elif [[ $note -ge 70 ]] then
  echo "C"
else
  echo "Échec"
fi

Ce script attribue une note en fonction de la valeur de la variable note. Il utilise elif pour gérer plusieurs conditions en séquence.

Les boucles

Les boucles permettent de répéter des blocs de code plusieurs fois. Voici deux types de boucles couramment utilisés en Bash :

Boucle for

La boucle for est utilisée pour itérer sur une liste de valeurs ou d'éléments. Par exemple, voici comment vous pouvez utiliser une boucle for pour parcourir une liste de fichiers :

#!/usr/bin/env bash

fichiers=$(ls)

for fichier in $fichiers; do
  echo "Nom du fichier : $fichier"
done

Ce script liste tous les fichiers du répertoire courant en utilisant la commande ls et les affiche un par un.

Boucle while

La boucle while permet d'exécuter un bloc de code tant qu'une condition spécifiée est vraie. Voici un exemple :

#!/usr/bin/env bash

compteur=1

while [[ $compteur -le 5 ]] do
  echo "Compteur : $compteur"
  compteur=$((compteur + 1))
done

Ce script affiche les valeurs de compteur de 1 à 5 en utilisant une boucle while.

Les tests

En Shell Bash, vous pouvez utiliser des tests conditionnels avec la commande if pour vérifier diverses conditions, y compris des tests sur les fichiers et des tests sur les entiers, sur les chaines de caractères...

Pour effectuer ces test on utilise les opérateurs de test.

Opérateurs de comparaison pour les entiers

Les tests sur les entiers vous permettent de comparer des valeurs numériques. Voici quelques exemples :

Vérifier si un nombre est égal à un autre nombre

On utilise dans ce cas l'opérateur de test -eq :

a=5
b=10

if [[ "$a" -eq "$b" ]] then
    echo "Les nombres sont égaux."
else
    echo "Les nombres ne sont pas égaux."
fi

Vérifier si un nombre est inférieur à un autre nombre

On utilise dans ce cas l'opérateur de test -lt :

a=5
b=10

if [[ "$a" -lt "$b" ]] then
    echo "$a est inférieur à $b."
else
    echo "$a n'est pas inférieur à $b."
fi

Vérifier si un nombre est supérieur à un autre nombre

On utilise dans ce cas l'opérateur de test -gt :

a=5
b=10

if [[ "$a" -gt "$b" ]] then
    echo "$a est supérieur à $b."
else
    echo "$a n'est pas supérieur à $b."
fi

Vérifier si un nombre est non nul

a=0

if [[ "$a" -ne 0 ]] then
    echo "Le nombre n'est pas nul."
else
    echo "Le nombre est nul."
fi

Opérateurs de comparaison pour les chaînes de caractères

Ces tests vous permettent de vérifier des conditions liées aux chaînes de caractères, comme leur égalité, leur longueur, leur présence dans une autre chaîne, etc

Vérifier si deux chaînes de caractères sont égales

On utilise dans ce cas l'opérateur de test = :

chaine1="Hello"
chaine2="World"

if [[ "$chaine1" = "$chaine2" ]] then
    echo "Les chaînes sont égales."
else
    echo "Les chaînes ne sont pas égales."
fi

Vous pouvez également utiliser == pour la comparaison de chaînes, bien que = soit plus couramment utilisé.

Vérifier si deux chaînes de caractères sont différentes

On remplace l'opérateur == par != :

chaine1="Hello"
chaine2="World"

if [[ "$chaine1" != "$chaine2" ]] then
    echo "Les chaînes sont différentes."
else
    echo "Les chaînes sont égales."
fi

Vérifier si une chaîne de caractères est vide

On utilise dans ce cas l'opérateur de test -z :

chaine=""

if [[ -z "$chaine" ]] then
    echo "La chaîne est vide."
else
    echo "La chaîne n'est pas vide."
fi

Vérifier si une chaîne de caractères n'est pas vide

On utilise dans ce cas l'opérateur de test -n :

chaine="Non vide"

if [[ -n "$chaine" ]] then
    echo "La chaîne n'est pas vide."
else
    echo "La chaîne est vide."
fi

Vérifier si une chaîne de caractères contient une sous-chaîne

On utilise dans ce cas l'opérateur de test == accompagné d'astérisques :

chaine="Bonjour tout le monde"

if [[ "$chaine" == *"tout"* ]]; then
    echo "La chaîne contient 'tout'."
else
    echo "La chaîne ne contient pas 'tout'."
fi

Dans cet exemple, * est utilisé pour faire correspondre n'importe quel nombre de caractères avant et après "tout".

Vérifier si une chaîne de caractères commence ou se termine par une certaine sous-chaîne

Il suffit de reprendre le test précédent en enlevant l'astérisque au début ou à la fin de la chaine de comparaison.

chaine="Bonjour"

if [[ "$chaine" == "Bon"* ]]; then
    echo "La chaîne commence par 'Bon'."
fi

if [[ "$chaine" == *"jour" ]]; then
    echo "La chaîne se termine par 'jour'."
fi

Vérifier la longueur d'une chaîne de caractères

chaine="Longueur"

if [[ ${#chaine} -gt 5 ]] then
    echo "La chaîne est plus longue que 5 caractères."
else
    echo "La chaîne n'est pas plus longue que 5 caractères."
fi

${#chaine} renvoie la longueur de la chaîne de caractères.

Les Opérateurs de tests sur les fichiers

Les tests sur les fichiers vous permettent de vérifier si un fichier existe, s'il est vide, s'il s'agit d'un répertoire, etc.

Vérifier si un fichier existe

On utilise dans ce cas l'opérateur de test -e :

if [[ -e "mon_fichier.txt" ]] then
    echo "Le fichier existe."
else
    echo "Le fichier n'existe pas."
fi

Vérifier si un fichier est un répertoire

On utilise dans ce cas l'opérateur de test -d :

if [[ -d "mon_repertoire" ]] then
    echo "C'est un répertoire."
else
    echo "Ce n'est pas un répertoire."
fi

Vérifier si un fichier est vide

On utilise dans ce cas l'opérateur de test -s :

if [[ -s "mon_fichier.txt" ]] then
    echo "Le fichier n'est pas vide."
else
    echo "Le fichier est vide."
fi

Vérifier si un fichier est exécutable

On utilise dans ce cas l'opérateur de test -x :

if [[ -x "mon_script.sh" ]] then
    echo "Le script est exécutable."
else
    echo "Le script n'est pas exécutable."
fi

Les Opérateurs de test logique

Ces opérateurs de test logique sont utilisés pour comibner plusieurs conditions.

-a : ET logique (e.g., [ condition1 -a condition2 ]) -o : OU logique (e.g., [ condition1 -o condition2 ]) ! : NON logique (e.g., !condition)

Utilisation des fonctions

En Shell Bash, les fonctions sont des blocs de code réutilisables qui effectuent une série d'instructions ou de commandes. Elles permettent de structurer et d'organiser un script Bash en regroupant des tâches spécifiques en fonctionnalités modulaires. Les fonctions en Bash peuvent recevoir des arguments, exécuter des opérations et renvoyer des valeurs. Voici comment créer et utiliser des fonctions en Shell Bash :

nom_de_la_fonction() {
    # Instructions de la fonction
    # ...
}

Voici un exemple simple de fonction Bash qui affiche un message :

afficher_message() {
    echo "Bonjour, ceci est un message de ma fonction."
}

Appel de fonctions

Pour appeler une fonction, utilisez simplement son nom suivi de parenthèses :

afficher_message

Lorsque vous appelez la fonction, le code à l'intérieur des accolades est exécuté.

Passage d'arguments

Vous pouvez passer des arguments à une fonction en les spécifiant entre les parenthèses lors de son appel. Les arguments sont accessibles à l'intérieur de la fonction via les variables spéciales $1, $2, etc., où $1 représente le premier argument, $2 le deuxième et ainsi de suite.

afficher_argument() {
    echo "Le premier argument est : $1"
}

afficher_argument "Hello"

Dans cet exemple, "Hello" est passé en tant que premier argument à la fonction afficher_argument.

Retour de valeurs

Pour renvoyer une valeur depuis une fonction, utilisez la commande return. Par exemple :

additionner() {
    local resultat=$(( $1 + $2 ))
    return $resultat
}

additionner 5 3
resultat=$?
echo "La somme est : $resultat"
La somme est : 8

Dans cet exemple, la fonction additionner prend deux arguments, effectue l'addition et renvoie le résultat à l'aide de return. Le résultat est ensuite stocké dans la variable $resultat à l'extérieur de la fonction.

Contrairement aux langages de programmation, les scripts bash ne permet de retourner qu'une seule valeur. Pour contourner ce manque, il est possible :

  • d'utiliser les paramètres de fonctions.
  • d'utiliser des varaibles globales.
  • de retourner une liste.

Variables locales

Notez que les variables déclarées à l'intérieur d'une fonction sont locales par défaut, ce qui signifie qu'elles ne sont accessibles qu'à l'intérieur de la fonction. Utilisez local pour déclarer des variables locales explicitement.

Utilisation d'arguments

Le passage d'arguments en Shell Bash fait référence à la capacité de passer des valeurs ou des données à un script ou à une fonction Bash lors de son exécution. Les arguments permettent de fournir des données dynamiques aux scripts ou aux fonctions, ce qui les rend plus flexibles et adaptables. Vous pouvez accéder à ces arguments à l'intérieur du script ou de la fonction et les utiliser pour effectuer des opérations spécifiques.

Les arguments passés à un script ou à une fonction Bash sont généralement représentés par des variables spéciales. Voici comment ils fonctionnent :

  • $0 : Il s'agit de la variable spéciale qui contient le nom du script lui-même ou le nom de la fonction s'il s'agit d'une fonction appelée depuis un script.

  • $1, $2, $3, ... $n : Ces variables spéciales contiennent les valeurs des arguments passés au script ou à la fonction. $1 correspond au premier argument, $2 au deuxième, $3 au troisième et ainsi de suite.

Voici un exemple simple pour illustrer le passage d'arguments dans un script Bash :

#!/usr/bin/env bash

echo "Le nom du script est : $0"
echo "Le premier argument est : $1"
echo "Le deuxième argument est : $2"

Si vous exécutez ce script avec la commande ./mon_script.sh argument1 argument2, vous obtiendrez la sortie suivante :

Le nom du script est : ./mon_script.sh
Le premier argument est : argument1
Le deuxième argument est : argument2

Comme vous pouvez le voir, les arguments passés lors de l'exécution du script sont accessibles en utilisant les variables spéciales $1, $2, etc.

Shift

La commande shift en Shell Bash est utilisée pour décaler les arguments passés à un script ou à une fonction. Elle permet de réorganiser les variables spéciales $1, $2, $3, etc., de manière à accéder aux arguments suivants.

Voici quelques exemples pour illustrer son utilisation :

  • Décalage d'un argument :
#!/usr/bin/env bash

echo "Le premier argument est : $1"
shift  # Décale les arguments d'une position
echo "Le nouveau premier argument est : $1"

Si vous exécutez ce script avec la commande ./mon_script.sh argument1 argument2, vous obtiendrez la sortie suivante :

Le premier argument est : argument1
Le nouveau premier argument est : argument2

Comme vous pouvez le voir, la commande shift a décalé les arguments, faisant de l'ancien $2 le nouveau $1.

  • Utilisation d'une boucle pour parcourir tous les arguments
#!/usr/bin/env bash

while [[ $# -gt 0 ]] do
    echo "Argument actuel : $1"
    shift
done

Ce script utilise une boucle while pour parcourir tous les arguments passés au script. La condition [ $# -gt 0 ] vérifie si le nombre d'arguments restants ($#) est supérieur à zéro. À chaque itération de la boucle, la commande shift décale les arguments, ce qui permet de traiter un argument à la fois.

Exit et les codes de sortie

Les codes de retour, également appelés codes de sortie, sont des valeurs numériques renvoyées par un programme ou un script lorsqu'il se termine. Ces codes sont utilisés pour indiquer le résultat de l'exécution du programme. En Shell Bash, vous pouvez définir des codes de sortie en utilisant la commande exit suivi du code numérique :

# Un script Bash simple avec un code de sortie personnalisé
# Exemple : ./mon_script.sh
if [ condition ]; then
    echo "Opération réussie."
    exit 0  # Code de sortie 0 pour succès
else
    echo "Opération échouée."
    exit 1  # Code de sortie 1 pour échec
fi

Quels codes de sorties utiliser ?

Il est courant d'utiliser 0 pour indiquer un succès (aucune erreur) et des valeurs non nulles pour indiquer des erreurs ou des problèmes spécifiques. Cependant, vous pouvez définir des codes de sortie personnalisés en fonction de vos besoins. Les valeurs de code de sortie ne sont pas limitées à 0 et 1 : vous pouvez utiliser n'importe quelle valeur numérique de 0 à 255.

Accès au code de sortie

Une fois que votre script se termine avec un code de sortie, vous pouvez accéder à ce code de sortie en utilisant la variable spéciale $?.

./mon_script.sh
echo $?
0

Débogage de scripts shell

Le débogage d'un script Shell Bash est essentiel pour identifier et corriger les erreurs, les bogues et les comportements inattendus dans votre code. Voici quelques techniques et outils que vous pouvez utiliser pour déboguer efficacement un script Bash :

Utilisation de l'option -x

L'une des méthodes les plus simples pour déboguer un script Bash consiste à exécuter le script avec l'option -x. Cela active le mode de débogage et affiche chaque commande exécutée avec sa sortie sur la console.

bash -x mon_script.sh

Ajout de messages de débogage

Vous pouvez insérer des messages de débogage dans votre script en utilisant la commande echo. Ajoutez des messages à des points clés de votre code pour afficher des informations sur les variables, les valeurs intermédiaires, les conditions, etc. Par exemple :

# Affiche la valeur de la variable $ma_variable
echo "ma_variable vaut : $ma_variable"

Ces messages vous aident à comprendre ce qui se passe à chaque étape de l'exécution.

Utilisation de la commande set -e

Vous pouvez utiliser set -e au début de votre script pour arrêter l'exécution dès qu'une commande renvoie un code de retour différent de zéro (erreur). Cela permet de détecter rapidement les erreurs et d'arrêter l'exécution du script en cas de problème.

# Arrêter le script en cas d'erreur
set -e

Utilisation de set -u

L'option set -u provoque une erreur si une variable non définie est utilisée dans votre script. Cela peut vous aider à éviter les erreurs causées par des variables non initialisées.

# Générer une erreur si une variable non définie est utilisée
set -u

Utilisation d'un débogueur Bash

Vous pouvez utiliser des débogueurs spécifiquement conçus pour Bash, tels que bashdb ou dbash. Ces outils vous permettent d'exécuter votre script pas à pas, de mettre en pause l'exécution à des points d'arrêt, de vérifier les valeurs des variables, etc.

Améliorer votre syntaxe avec shellcheck

ShellCheck est un outil d'analyse statique de scripts Shell Bash qui vous aide à repérer les erreurs de syntaxe, les problèmes de style et les vulnérabilités potentielles dans vos scripts Bash.

Installation de shellcheck

shellcheck est disponible sur la plupart des distributions linux via le gestionnaire de packages. Par exemple sur une Ubuntu :

sudo apt install shellcheck

Utilisation de shellcheck

Le fonctionnement est assez simple puisqu'il suffit de taper son nom suivi du nom du script à analyser :

shellcheck mon_script.sh

ShellCheck parcourra votre script et signalera tout problème qu'il trouve, en indiquant la ligne et la colonne exactes du code problématique, ainsi qu'une description du problème.

Par exemple, si vous avez un script avec une erreur de syntaxe, ShellCheck pourrait afficher quelque chose comme :

mon_script.sh:3:3: error: unexpected EOF, closing token `fi' [SC1009]

Cela vous indique que sur la ligne 3, colonne 3, il y a une erreur de syntaxe liée à la structure fi.

Utiliser l'outil de formatage shfmt

shfmt est un outil de formatage de fichiers Shell, dont le langage Bash. shfmt permet de reformater automatiquement le code source pour suivre une convention de style particulière. Il aide à maintenir la cohérence du code, à améliorer la lisibilité et à suivre des règles de formatage spécifiques.

Installation de shfmt

shfmt est disponible sur la plupart des distributions linux via le gestionnaire de packages. Par exemple sur une Ubuntu :

sudo apt install shfmt

Utilisation de shfmt

Comme pour shellcheck, il suffit de lancer la commande shfmt suivi du nom de votre fichier de scripts :

shfmt mon_script.sh

Ajouter des Tests dans vos scripts Bash

Il existe un framework appelé Bats permettant définir des tests unitaires dans les scripts Bash.

Comprendre les messages d'erreur

Chaque message d'erreur généré par ShellCheck est accompagné d'un code d'erreur [SCxxxx] qui vous permet de rechercher des informations détaillées sur le problème spécifique sur le site de ShellCheck.

Conseil

Utilisez l'outil shellcheck dès le démarrage de votre projet de script. L'utiliser à la fin ou sur un script existant peut tourner au cauchemar !

Bonnes pratiques

L'utilisation de bonnes pratiques dans le développement de scripts Shell sont essentielles pour écrire des scripts fiables, lisibles et faciles à maintenir. Voici quelques recommandations pour vous aider à écrire des scripts Shell de haute qualité :

Respectez les conventions locales

Si vous travaillez dans un environnement où des conventions de codage spécifiques sont en place, Respectez-les !

Stockez vos scripts dans un gestionnaire de contrôle de code

Un script shell est un programme, il doit être stocké dans un gestionnaire de contrôle de code et posséder un pipeline ci/cd complet.

Commentez votre code

Ajoutez des commentaires explicatifs pour expliquer ce que fait chaque partie de votre script. Les commentaires aident les autres développeurs (et vous-même) à comprendre rapidement le code.

Utilisez un en-tête explicite

Commencez votre script par un en-tête qui explique son but, son auteur, sa date de création et toute autre information pertinente. Cela rend votre script plus compréhensible pour les autres et pour vous-même lorsque vous le relisez plus tard.

#!/usr/bin/env bash
# Auteur : VotreNom
# Date de création : 2023-11-02
# But : Description du but du script

Choisissez un interpréteur Shell explicite

Spécifiez explicitement l'interpréteur Shell que vous souhaitez utiliser en utilisant la ligne de shebang (#!/usr/bin/env bash pour Bash). Cela garantit que votre script est exécuté avec l'interpréteur approprié, sinon cela peut entraîner des erreurs car la syntaxe diffère entre chaque interpréteur Shell.

Indentation cohérente

Indentez votre code de manière cohérente pour rendre la structure du script plus lisible. Utilisez généralement des espaces ou des tabulations (conformément à la convention de votre choix) pour l'indentation.

Utilisez des noms de variables significatifs

Choisissez des noms de variables descriptifs qui indiquent leur but. Évitez les noms de variables courts ou obscurs.

Évitez d'utiliser des variables globales

Privilégiez l'utilisation de variables locales dans les fonctions plutôt que de variables globales. Cela limite la portée des variables et évite les conflits potentiels.

Gérez les erreurs correctement

Ajoutez des mécanismes de gestion d'erreurs pour gérer les cas où les commandes échouent. Vous pouvez utiliser des structures if pour vérifier les codes de retour des commandes et prendre des mesures en conséquence.

Utilisez des fonctions

Découpez votre code en fonctions logiques pour améliorer la lisibilité et la réutilisabilité. Les fonctions permettent également d'encapsuler la logique complexe.

Validez les entrées utilisateur

Si votre script accepte des entrées utilisateur, assurez-vous de les valider pour éviter les vulnérabilités de sécurité et les erreurs.

Gestion des fichiers temporaires

Si votre script crée des fichiers temporaires, assurez-vous de les créer de manière sécurisée, de les nettoyer après utilisation et de gérer les erreurs de manière appropriée.

Testez votre script

Testez votre script sur différents scénarios pour vous assurer qu'il fonctionne correctement. L'utilisation de tests automatisés est recommandée.

Mise à jour et maintenance

Assurez-vous de mettre à jour et de maintenir régulièrement vos scripts pour les adapter aux changements de configuration, aux nouvelles versions d'interpréteurs Shell, etc.

Plus d'infos

astuce

Je vous conseille d'acheter un livre qui vous servira durant les premières années de votre carrière.

Livres gratuits

Livres

MOOC

Sites

Vidéos