Aller au contenu
Administration Linux medium

Développer des scripts shell

32 min de lecture

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.

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 script 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 !

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.

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 :

Fenêtre de terminal
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 :

Fenêtre de terminal
sudo apt install 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.

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 :

    Fenêtre de terminal
    # 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 :

    Fenêtre de terminal
    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 importante en Bash que dans certains autres langages, il est recommandé d’indenter votre code afin d’en améliorer la lisibilité.

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.

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)

Fenêtre de terminal
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 :

Fenêtre de terminal
declare -i x=35*2

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 :

Fenêtre de terminal
nom="John"
age=30

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 :

Fenêtre de terminal
echo "Mon nom est $nom et j'ai $age ans."

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.

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

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.

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 !"

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.

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

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 permettent de répéter des blocs de code plusieurs fois. Voici deux types de boucles couramment utilisés en Bash :

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.

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.

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.

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

Section intitulée « Vérifier si un nombre est égal à un autre nombre »

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

Fenêtre de terminal
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

Section intitulée « Vérifier si un nombre est inférieur à un autre nombre »

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

Fenêtre de terminal
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

Section intitulée « Vérifier si un nombre est supérieur à un autre nombre »

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

Fenêtre de terminal
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
Fenêtre de terminal
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

Section intitulée « 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

Section intitulée « Vérifier si deux chaînes de caractères sont égales »

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

Fenêtre de terminal
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

Section intitulée « Vérifier si deux chaînes de caractères sont différentes »

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

Fenêtre de terminal
chaine1="Hello"
chaine2="World"
if [[ "$chaine1" != "$chaine2" ]] then
echo "Les chaînes sont différentes."
else
echo "Les chaînes sont égales."
fi

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

Fenêtre de terminal
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

Section intitulée « Vérifier si une chaîne de caractères n’est pas vide »

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

Fenêtre de terminal
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

Section intitulée « 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 :

Fenêtre de terminal
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

Section intitulée « 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.

Fenêtre de terminal
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

Section intitulée « Vérifier la longueur d’une chaîne de caractères »
Fenêtre de terminal
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 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.

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

Fenêtre de terminal
if [[ -e "mon_fichier.txt" ]] then
echo "Le fichier existe."
else
echo "Le fichier n'existe pas."
fi

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

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

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

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

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

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

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)

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 :

Fenêtre de terminal
nom_de_la_fonction() {
# Instructions de la fonction
# ...
}

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

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

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

Fenêtre de terminal
afficher_message

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

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.

Fenêtre de terminal
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.

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

Fenêtre de terminal
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.

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.

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.

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.

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 :

./mon_script.sh
# Un script Bash simple avec un code de sortie personnalisé
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

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.

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 $?.

Fenêtre de terminal
./mon_script.sh
echo $?
0

Le débogage d’un script Shell 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 :

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.

Fenêtre de terminal
bash -x mon_script.sh

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 :

Fenêtre de terminal
# 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.

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.

Fenêtre de terminal
# Arrêter le script en cas d'erreur
set -e

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.

Fenêtre de terminal
# Générer une erreur si une variable non définie est utilisée
set -u

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.

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

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

Fenêtre de terminal
sudo apt install shellcheck

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

Fenêtre de terminal
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 :

Fenêtre de terminal
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.

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.

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 !

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.

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

Fenêtre de terminal
sudo apt install shfmt

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

Fenêtre de terminal
shfmt mon_script.sh

Pour rendre vos scripts Shell plus fiables, sûrs et faciles à maintenir, voici une série de bonnes pratiques indispensables, tirées des meilleurs conseils :

  • Validez les entrées utilisateur : Toujours vérifier et nettoyer les données d’entrée pour éviter les injections de commande et les erreurs.
  • Citez vos variables : Protégez vos variables avec des guillemets pour éviter des erreurs liées à la séparation des mots ou à l’expansion des globbing.
  • Gérez les erreurs : Utilisez set -euo pipefail pour arrêter le script à la moindre erreur et ajoutez des vérifications des retours de commandes.
  • Utilisez des chemins absolus : Garantissez que les bonnes commandes sont utilisées et non celles manipulées par une variable PATH.
  • Protégez les fichiers temporaires : Créez des fichiers temporaires de manière sécurisée avec mktemp et nettoyez-les après utilisation.

Ces bonnes pratiques vous protégeront des erreurs courantes et des failles de sécurité. Pour une version complète et détaillée des pratiques sécurisées en Bash, consultez mon guide sur les scripts shell sécurisés.